Mic*_*ato 5 xml android android-jetpack-compose
AppBarLayout 中的属性允许当关联的视图滚动时(通常是 a或 a 内的任何内容app:liftOnScroll="true"),视图会显示为抬起的状态(基本上在底部添加一条小线的高度阴影)。app:layout_behavior="@string/appbar_scrolling_view_behavior"RecyclerViewScrolelView
Jetpack Compose 中有类似的东西吗?我无法找到兼容的行为,无论是与TopAppBar常规还是与常规Text(在其任何参数或修饰符中)。
简而言之 - 有没有什么方法可以提升类似工具栏的视图,但只有当底层列表/可滚动内容滚动时(而不是在顶部)?
不幸的是它还不支持。但您可以自己创建它。您需要使用可滚动组件包装主要内容,并根据主要内容的滚动状态对 AppBar 的高度进行动画处理。
这是示例:
/**
* AppBarScaffold displays TopAppBar above specified content. Content is wrapped with
* scrollable Column. TopAppBar's elevation is animated depending on content scroll state.
*
* Back arrow is shown only if [onBackPress] is not null
*
* @param onBackPress Call back when back arrow icon is pressed
*/
@Composable
fun AppBarScaffold(
modifier: Modifier = Modifier,
title: String = "",
onBackPress: (() -> Unit)? = null,
actions: @Composable RowScope.() -> Unit = {},
content: @Composable () -> Unit
) {
val scrollState = rememberScrollState()
val contentColor = contentColorFor(MaterialTheme.colors.background)
val elevation by animateDpAsState(if (scrollState.value == 0) 0.dp else AppBarDefaults.TopAppBarElevation)
Surface(
modifier = modifier.statusBarsPadding(),
color = MaterialTheme.colors.background,
contentColor = contentColor
) {
val topBar = @Composable { AppBar(title, onBackPress, actions, elevation) }
val body = @Composable {
Column(modifier = Modifier.verticalScroll(state = scrollState)) {
content()
}
}
SubcomposeLayout { constraints ->
val layoutWidth = constraints.maxWidth
val layoutHeight = constraints.maxHeight
val looseConstraints = constraints.copy(minWidth = 0, minHeight = 0)
layout(layoutWidth, layoutHeight) {
val topBarPlaceables = subcompose(AppBarContent.AppBar, topBar).map {
it.measure(looseConstraints)
}
val topBarHeight = topBarPlaceables.maxByOrNull { it.height }?.height ?: 0
val bodyContentHeight = layoutHeight - topBarHeight
val bodyContentPlaceables = subcompose(AppBarContent.MainContent) {
body()
}.map { it.measure(looseConstraints.copy(maxHeight = bodyContentHeight)) }
bodyContentPlaceables.forEach {
it.place(0, topBarHeight)
}
topBarPlaceables.forEach {
it.place(0, 0)
}
}
}
}
}
@Composable
fun BackArrow(onclick: () -> Unit) {
IconButton(onClick = { onclick() }) {
Icon(imageVector = Icons.Default.ArrowBack, "Back Arrow")
}
}
@Composable
private fun AppBar(
title: String = "",
onBackPress: (() -> Unit)? = null,
actions: @Composable RowScope.() -> Unit = {},
elevation: Dp
) {
var navigationIcon: @Composable (() -> Unit)? = null
onBackPress?.let {
navigationIcon = { BackArrow { onBackPress.invoke() } }
}
Surface(
color = MaterialTheme.colors.background,
contentColor = MaterialTheme.colors.onBackground,
elevation = elevation,
shape = RectangleShape
) {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier.fillMaxWidth().padding(AppBarDefaults.ContentPadding).height(AppBarHeight)
) {
navigationIcon?.let {
Row(TitleIconModifier.align(Alignment.CenterStart), verticalAlignment = Alignment.CenterVertically) {
CompositionLocalProvider(
LocalContentAlpha provides ContentAlpha.high,
content = it
)
}
}
Row(
horizontalArrangement = Arrangement.Center,
modifier = Modifier.fillMaxWidth(0.5f).fillMaxHeight(),
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = title,
style = MaterialTheme.typography.h4,
textAlign = TextAlign.Center
)
}
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {
Row(
Modifier.align(Alignment.CenterEnd).fillMaxHeight(),
horizontalArrangement = Arrangement.End,
verticalAlignment = Alignment.CenterVertically,
content = actions
)
}
}
}
}
private val AppBarHorizontalPadding = 4.dp
private val TitleIconModifier = Modifier.fillMaxHeight().width(72.dp - AppBarHorizontalPadding)
private val AppBarHeight = 56.dp
enum class AppBarContent {
AppBar,
MainContent
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2331 次 |
| 最近记录: |