我看了很多关于jetpack中顶级应用程序栏崩溃的问题,比如Jetpack组合折叠工具栏,植物细节视图等等,但是没有一个教程/例子使用Scaffold。因此,这个问题。
按照android 文档中给出的示例,我对其进行了一些修改,以便将其与脚手架一起使用。
// here we use LazyColumn that has a build-in nested scroll, but we want to act like a
// parent for this LazyColumn and participate in its nested scroll.
// Let's make a collapsing toolbar for LazyColumn
val toolbarHeight = 48.dp
val toolbarHeightPx = with(LocalDensity.current) { toolbarHeight.roundToPx().toFloat() }
// our offset to collapse toolbar
val toolbarOffsetHeightPx = remember { mutableStateOf(0f) }
// now, let's create connection to the nested scroll system and listen to the scroll
// happening inside child LazyColumn
val nestedScrollConnection = remember {
object : NestedScrollConnection {
override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
// try to consume before LazyColumn to collapse toolbar if needed, hence pre-scroll
val delta = available.y
val newOffset = toolbarOffsetHeightPx.value + delta
toolbarOffsetHeightPx.value = newOffset.coerceIn(-toolbarHeightPx, 0f)
// here's the catch: let's pretend we consumed 0 in any case, since we want
// LazyColumn to scroll anyway for good UX
// We're basically watching scroll without taking it
return Offset.Zero
}
}
}
Scaffold(
topBar = {
TopAppBar(
modifier = Modifier
.height(toolbarHeight)
.offset { IntOffset(x = 0, y = toolbarOffsetHeightPx.value.roundToInt()) },
title = { Text("toolbar offset is ${toolbarOffsetHeightPx.value}") }
)
}
) {
Box(
Modifier
.fillMaxSize()
// attach as a parent to the nested scroll system
.nestedScroll(nestedScrollConnection)
) {
// our list with build in nested scroll support that will notify us about its scroll
LazyColumn {
items(100) { index ->
Text("I'm item $index", modifier = Modifier
.fillMaxWidth()
.padding(16.dp))
}
}
}
}
输出结果不像预期的那样。顶部应用程序栏倾向于向上移动,但TopBar在支架中的高度保持不变,因此列表开始消失在顶部应用程序栏的高度。
所以,我的问题是如何计算顶部应用程序栏的高度,以便根据偏移量进行更改。
我试过了
height - y offset value
但这行不通。
发布于 2022-08-13 07:57:44
将Modifier.nestedScroll
和scrollBehavior
与Scaffold
组合结合使用,可以提高系统的开发能力。
@OptIn(ExperimentalMaterial3Api::class)
@Preview
@Composable
fun TopBarton() {
val appBarState = rememberTopAppBarState()
val scrollBehavior = remember { TopAppBarDefaults.enterAlwaysScrollBehavior(appBarState) }
Scaffold(
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
topBar = {
SmallTopAppBar(
title = { Text("TopBarton") },
navigationIcon = {
IconButton(onClick = { /* ... */ }) {
Icon(
imageVector = Icons.Filled.Menu,
contentDescription = null
)
}
},
actions = {
IconButton(onClick = { /* ... */ }) {
Icon(
imageVector = Icons.Filled.Star,
contentDescription = null
)
}
},
scrollBehavior = scrollBehavior
)
},
content = { innerPadding ->
LazyColumn(
contentPadding = innerPadding,
verticalArrangement = Arrangement.spacedBy(9.dp)
) {
val list = (0..100).map { it.toString() }
items(count = list.size) {
Text(
text = list[it],
style = MaterialTheme.typography.bodyLarge,
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 18.dp)
)
}
}
}
)
}
发布于 2022-08-02 15:10:38
实际上,Scaffold
对我在上面的评论中提到的答案没有多大影响。请看下面的代码。
你只需要适应你的需要..。
@ExperimentalFoundationApi
@Composable
fun CollapsingEffectScreen() {
val items = (1..100).map { "Item $it" }
val lazyListState = rememberLazyListState()
var scrolledY = 0f
var previousOffset = 0
Scaffold {
LazyColumn(
Modifier
.fillMaxSize()
.padding(it),
lazyListState,
) {
item {
TopAppBar(
Modifier
.graphicsLayer {
scrolledY += lazyListState.firstVisibleItemScrollOffset - previousOffset
translationY = scrolledY * 0.5f
previousOffset = lazyListState.firstVisibleItemScrollOffset
}
.height(240.dp)
.fillMaxWidth()
) {
Image(
modifier = Modifier.fillMaxWidth().wrapContentHeight(),
painter = painterResource(id = R.drawable.recife),
contentDescription = null,
contentScale = ContentScale.FillWidth,
)
}
}
items(items) {
Text(
text = it,
Modifier
.background(MaterialTheme.colors.surface)
.fillMaxWidth()
.padding(8.dp)
)
}
}
}
}
https://stackoverflow.com/questions/73194161
复制相似问题