Fix: BookInfoTopBar's Container color does not change into Scrolled container color, even when overlapping.

This commit is contained in:
acclorite 2024-08-03 12:50:45 +03:00
parent 7756006329
commit 3d8e0b5f54
3 changed files with 23 additions and 36 deletions

View file

@ -1,6 +1,6 @@
package ua.acclorite.book_story.presentation.components
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.FastOutLinearInEasing
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.spring
import androidx.compose.animation.fadeIn
@ -18,19 +18,20 @@ import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.TopAppBarScrollBehavior
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.lerp
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import ua.acclorite.book_story.R
/**
* Animated top app bar. Has up to 3 different top bars inside it. Follow [TopAppBar] for more info.
* Animated top app bar.
* Has up to 3 different top bars inside it. Follow [TopAppBar] for more info.
*
* @param containerColor Container color of the TopBar.
* @param scrolledContainerColor Scrolled container color of the TopBar.
* @param scrollBehavior [TopAppBarScrollBehavior].
* @param isTopBarScrolled Whether isScrolled state should be forced or not.
* @param content1Visibility Whether first top app bar should be shown.
* @param content2Visibility Whether second top app bar should be shown.
@ -66,7 +67,7 @@ fun AnimatedTopAppBar(
WindowInsets.statusBars.getTop(density).toDp()
}
if (containerColor != Color.Transparent) {
if (containerColor.alpha != 0f) {
Box(
modifier = Modifier
.fillMaxWidth()
@ -78,22 +79,18 @@ fun AnimatedTopAppBar(
)
}
val scrollableContainerColor by remember(isTopBarScrolled) {
derivedStateOf {
if (isTopBarScrolled == true) {
scrolledContainerColor
} else {
containerColor
}
}
val animatedContainerColor = remember(
containerColor,
scrolledContainerColor,
isTopBarScrolled
) {
lerp(
containerColor,
scrolledContainerColor,
FastOutLinearInEasing.transform(if (isTopBarScrolled == true) 1f else 0f)
)
}
val animatedContainerColor by animateColorAsState(
targetValue = scrollableContainerColor,
animationSpec = spring(stiffness = Spring.StiffnessMediumLow),
label = stringResource(id = R.string.top_app_bar_anim_content_desc)
)
CustomAnimatedVisibility(
visible = content1Visibility ?: true,
enter = fadeIn(spring(stiffness = Spring.StiffnessMediumLow)),

View file

@ -27,7 +27,6 @@ import androidx.compose.material.icons.filled.PlayArrow
import androidx.compose.material.pullrefresh.PullRefreshIndicator
import androidx.compose.material.pullrefresh.pullRefresh
import androidx.compose.material.pullrefresh.rememberPullRefreshState
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.FloatingActionButtonDefaults
import androidx.compose.material3.Icon
@ -35,7 +34,6 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
@ -44,7 +42,6 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
@ -109,7 +106,7 @@ fun BookInfoScreenRoot(screen: Screen.BookInfo) {
)
}
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterialApi::class)
@OptIn(ExperimentalMaterialApi::class)
@Composable
private fun BookInfoScreen(
state: State<BookInfoState>,
@ -120,7 +117,6 @@ private fun BookInfoScreen(
onHistoryEvent: (HistoryEvent) -> Unit
) {
val context = LocalContext.current
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()
val listState = rememberLazyListState()
val snackbarState = remember { SnackbarHostState() }
val refreshState = rememberPullRefreshState(
@ -179,8 +175,7 @@ private fun BookInfoScreen(
.fillMaxSize()
.imePadding()
.windowInsetsPadding(WindowInsets.navigationBars)
.pullRefresh(refreshState)
.nestedScroll(scrollBehavior.nestedScrollConnection),
.pullRefresh(refreshState),
containerColor = MaterialTheme.colorScheme.surface,
topBar = {
BookInfoTopBar(
@ -189,7 +184,6 @@ private fun BookInfoScreen(
onLibraryEvent = onLibraryEvent,
onHistoryEvent = onHistoryEvent,
onNavigate = onNavigate,
scrollBehavior = scrollBehavior,
listState = listState,
snackbarState = snackbarState
)

View file

@ -12,13 +12,11 @@ import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarScrollBehavior
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.style.TextOverflow
import ua.acclorite.book_story.R
@ -42,7 +40,6 @@ import ua.acclorite.book_story.presentation.ui.Transitions
* @param onLibraryEvent [LibraryEvent] callback.
* @param onHistoryEvent [HistoryEvent] callback.
* @param onNavigate Navigator callback.
* @param scrollBehavior [TopAppBarScrollBehavior].
* @param listState [LazyListState].
* @param snackbarState [SnackbarHostState].
*/
@ -54,7 +51,6 @@ fun BookInfoTopBar(
onLibraryEvent: (LibraryEvent) -> Unit,
onHistoryEvent: (HistoryEvent) -> Unit,
onNavigate: OnNavigate,
scrollBehavior: TopAppBarScrollBehavior,
listState: LazyListState,
snackbarState: SnackbarHostState
) {
@ -62,9 +58,9 @@ fun BookInfoTopBar(
val firstVisibleItemIndex by remember { derivedStateOf { listState.firstVisibleItemIndex } }
AnimatedTopAppBar(
containerColor = Color.Transparent,
scrollBehavior = scrollBehavior,
isTopBarScrolled = null,
containerColor = MaterialTheme.colorScheme.surface.copy(0f),
scrollBehavior = null,
isTopBarScrolled = listState.canScrollBackward,
content1NavigationIcon = {
if (