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 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.core.spring import androidx.compose.animation.core.spring
import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeIn
@ -18,19 +18,20 @@ import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.TopAppBarScrollBehavior import androidx.compose.material3.TopAppBarScrollBehavior
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.lerp
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp 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 isTopBarScrolled Whether isScrolled state should be forced or not.
* @param content1Visibility Whether first top app bar should be shown. * @param content1Visibility Whether first top app bar should be shown.
* @param content2Visibility Whether second 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() WindowInsets.statusBars.getTop(density).toDp()
} }
if (containerColor != Color.Transparent) { if (containerColor.alpha != 0f) {
Box( Box(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
@ -78,21 +79,17 @@ fun AnimatedTopAppBar(
) )
} }
val scrollableContainerColor by remember(isTopBarScrolled) { val animatedContainerColor = remember(
derivedStateOf { containerColor,
if (isTopBarScrolled == true) { scrolledContainerColor,
scrolledContainerColor isTopBarScrolled
} else { ) {
containerColor 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( CustomAnimatedVisibility(
visible = content1Visibility ?: true, visible = content1Visibility ?: true,

View file

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

View file

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