AnimatedTopAppBar: New custom content option, to also change scrollable color for content below.
This commit is contained in:
parent
3d8e0b5f54
commit
b1ebe72cc3
3 changed files with 93 additions and 84 deletions
|
|
@ -1,16 +1,17 @@
|
|||
package ua.acclorite.book_story.presentation.components
|
||||
|
||||
import androidx.compose.animation.core.FastOutLinearInEasing
|
||||
import androidx.compose.animation.core.Spring
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.animation.core.spring
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.ColumnScope
|
||||
import androidx.compose.foundation.layout.RowScope
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.statusBars
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
|
|
@ -18,12 +19,11 @@ import androidx.compose.material3.TopAppBar
|
|||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.TopAppBarScrollBehavior
|
||||
import androidx.compose.runtime.Composable
|
||||
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.unit.dp
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import ua.acclorite.book_story.R
|
||||
|
||||
/**
|
||||
* Animated top app bar.
|
||||
|
|
@ -36,6 +36,7 @@ import androidx.compose.ui.unit.dp
|
|||
* @param content1Visibility Whether first top app bar should be shown.
|
||||
* @param content2Visibility Whether second top app bar should be shown.
|
||||
* @param content3Visibility Whether third top app bar should be shown.
|
||||
* @param customContent Custom content below [TopAppBar].
|
||||
*/
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
|
|
@ -59,38 +60,28 @@ fun AnimatedTopAppBar(
|
|||
content3Visibility: Boolean? = null,
|
||||
content3NavigationIcon: @Composable () -> Unit = {},
|
||||
content3Title: @Composable () -> Unit = {},
|
||||
content3Actions: @Composable RowScope.() -> Unit = {}
|
||||
content3Actions: @Composable RowScope.() -> Unit = {},
|
||||
|
||||
customContent: @Composable ColumnScope.() -> Unit = {}
|
||||
) {
|
||||
val animatedContainerColor = lerp(
|
||||
containerColor,
|
||||
scrolledContainerColor,
|
||||
animateFloatAsState(
|
||||
if (isTopBarScrolled == true) 1f else 0f,
|
||||
animationSpec = spring(
|
||||
stiffness = Spring.StiffnessMediumLow
|
||||
),
|
||||
label = stringResource(id = R.string.top_app_bar_anim_content_desc)
|
||||
).value
|
||||
)
|
||||
|
||||
Column(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.background(animatedContainerColor)
|
||||
) {
|
||||
Box(modifier = Modifier.fillMaxWidth()) {
|
||||
val density = LocalDensity.current
|
||||
val statusBarPadding = with(density) {
|
||||
WindowInsets.statusBars.getTop(density).toDp()
|
||||
}
|
||||
|
||||
if (containerColor.alpha != 0f) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(64.dp + statusBarPadding)
|
||||
.background(
|
||||
if (isTopBarScrolled == true) scrolledContainerColor
|
||||
else containerColor
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
val animatedContainerColor = remember(
|
||||
containerColor,
|
||||
scrolledContainerColor,
|
||||
isTopBarScrolled
|
||||
) {
|
||||
lerp(
|
||||
containerColor,
|
||||
scrolledContainerColor,
|
||||
FastOutLinearInEasing.transform(if (isTopBarScrolled == true) 1f else 0f)
|
||||
)
|
||||
}
|
||||
|
||||
CustomAnimatedVisibility(
|
||||
visible = content1Visibility ?: true,
|
||||
enter = fadeIn(spring(stiffness = Spring.StiffnessMediumLow)),
|
||||
|
|
@ -104,7 +95,8 @@ fun AnimatedTopAppBar(
|
|||
scrollBehavior = scrollBehavior,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
colors = TopAppBarDefaults.topAppBarColors(
|
||||
containerColor = animatedContainerColor,
|
||||
containerColor = if (isTopBarScrolled != null) Color.Transparent
|
||||
else containerColor,
|
||||
scrolledContainerColor = scrolledContainerColor
|
||||
)
|
||||
)
|
||||
|
|
@ -124,7 +116,8 @@ fun AnimatedTopAppBar(
|
|||
scrollBehavior = scrollBehavior,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
colors = TopAppBarDefaults.topAppBarColors(
|
||||
containerColor = animatedContainerColor,
|
||||
containerColor = if (isTopBarScrolled != null) Color.Transparent
|
||||
else containerColor,
|
||||
scrolledContainerColor = scrolledContainerColor
|
||||
)
|
||||
)
|
||||
|
|
@ -145,13 +138,16 @@ fun AnimatedTopAppBar(
|
|||
scrollBehavior = scrollBehavior,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
colors = TopAppBarDefaults.topAppBarColors(
|
||||
containerColor = animatedContainerColor,
|
||||
containerColor = if (isTopBarScrolled != null) Color.Transparent
|
||||
else containerColor,
|
||||
scrolledContainerColor = scrolledContainerColor
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
customContent()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -33,12 +33,14 @@ import ua.acclorite.book_story.presentation.screens.library.data.LibraryEvent
|
|||
* Tab row, either scrollable or static, depends on screen width.
|
||||
*
|
||||
* @param onEvent Event used to Scroll to Page.
|
||||
* @param itemCountBackgroundColor Item count background color.
|
||||
* @param books The list of all books.
|
||||
* @param pagerState [PagerState].
|
||||
*/
|
||||
@Composable
|
||||
fun LibraryTabRow(
|
||||
onEvent: (LibraryEvent) -> Unit,
|
||||
itemCountBackgroundColor: Color,
|
||||
books: List<CategorizedBooks>,
|
||||
pagerState: PagerState
|
||||
) {
|
||||
|
|
@ -113,7 +115,7 @@ fun LibraryTabRow(
|
|||
text = tabItem.second.toString(),
|
||||
modifier = Modifier
|
||||
.background(
|
||||
MaterialTheme.colorScheme.surfaceContainer,
|
||||
itemCountBackgroundColor,
|
||||
MaterialTheme.shapes.medium
|
||||
)
|
||||
.padding(horizontal = 8.dp, vertical = 4.dp),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
package ua.acclorite.book_story.presentation.screens.library.components
|
||||
|
||||
import androidx.compose.animation.animateColorAsState
|
||||
import androidx.compose.animation.core.Spring
|
||||
import androidx.compose.animation.core.spring
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
|
|
@ -168,12 +171,20 @@ fun LibraryTopBar(
|
|||
},
|
||||
content3Actions = {
|
||||
MoreDropDown()
|
||||
}
|
||||
)
|
||||
},
|
||||
customContent = {
|
||||
LibraryTabRow(
|
||||
onEvent = onEvent,
|
||||
books = state.value.categorizedBooks,
|
||||
itemCountBackgroundColor = animateColorAsState(
|
||||
if (state.value.hasSelectedItems) MaterialTheme.colorScheme.surfaceContainerHighest
|
||||
else MaterialTheme.colorScheme.surfaceContainer,
|
||||
animationSpec = spring(stiffness = Spring.StiffnessMediumLow),
|
||||
label = stringResource(id = R.string.top_app_bar_anim_content_desc)
|
||||
).value,
|
||||
pagerState = pagerState
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue