Jetpack Compose 折叠工具栏

Mer*_*rig 7 android kotlin android-jetpack android-jetpack-compose

我找不到有关此事的任何文档,是否有类似于CollapsingToolbarCompose 中的内容?

我发现的只是这里提到了它,但没有关于如何设置它

Man*_*eru 41

Material Design 3的 Jetpack Compose 实现包括 4 种类型的顶级应用栏 ( https://m3.material.io/components/top-app-bar/implementation ):

  • CenterAlignedTopAppBar
  • SmallTopAppBar
  • MediumTopAppBar
  • LargeTopAppBar

https://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary

它们都有一个scrollBehavior参数,可用于折叠工具栏。库中有 3 种基本类型的滚动行为:

  • TopAppBarDefaults.pinnedScrollBehavior
  • TopAppBarDefaults.enterAlwaysScrollBehavior
  • TopAppBarDefaults.exitUntilCollapsedScrollBehavior

https://developer.android.com/reference/kotlin/androidx/compose/material3/TopAppBarDefaults

注意:此 API 目前被注释为实验性的。

使用示例:

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun Test() {
    val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior(rememberTopAppBarState())
    Scaffold(
        modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
        topBar = {
            MediumTopAppBar(
                title = { Text(text = "Scroll Behavior Test") },
                navigationIcon = {
                    IconButton(onClick = { /*TODO*/ }) {
                        Icon(imageVector = Icons.Default.Menu, contentDescription = "")
                    }
                },
                scrollBehavior = scrollBehavior
            )
        }
    ) {
        LazyColumn(modifier = Modifier.fillMaxWidth()) {
            items((1..50).toList()) { item ->
                Text(modifier = Modifier.padding(8.dp), text = "Item $item")
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 当使用“LargeTopAppBar”时,有没有办法对其进行自定义,以便当它处于高状态(即向下拖动)时,显示与处于较小/折叠状态时完全不同的可组合项? (2认同)

ngl*_*ber 19

我找到了 Samir Basnet(来自 Kotlin Slack Channel)创建的解决方案,这对我很有用,我希望它对其他人有帮助......

@Composable
fun CollapsingEffectScreen() {
    val items = (1..100).map { "Item $it" }
    val lazyListState = rememberLazyListState()
    var scrolledY = 0f
    var previousOffset = 0
    LazyColumn(
        Modifier.fillMaxSize(),
        lazyListState,
    ) {
        item {
            Image(
                painter = painterResource(id = R.drawable.recife),
                contentDescription = null,
                contentScale = ContentScale.FillWidth,
                modifier = Modifier
                    .graphicsLayer {
                        scrolledY += lazyListState.firstVisibleItemScrollOffset - previousOffset
                        translationY = scrolledY * 0.5f
                        previousOffset = lazyListState.firstVisibleItemScrollOffset
                    }
                    .height(240.dp)
                    .fillMaxWidth()
            )
        }
        items(items) {
            Text(
                text = it,
                Modifier
                    .background(Color.White)
                    .fillMaxWidth()
                    .padding(8.dp)
            )
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

结果如下:

在此输入图像描述

  • 此解决方案很有帮助,并且与 Android Doc 的折叠工具栏示例不同,因为它仅允许在列表位于顶部时展开折叠项目。谢谢你的回答 (3认同)

sit*_*ech 7

您可以使用compose-collapsing-toolbar库。

安装implementation "me.onebone:toolbar-compose:2.1.0"

用法-示例

预览

以下是该库 Readme.md 中的一些 gif 图像:

jetpack 撰写折叠工​​具栏 jetpack compose 折叠工具栏|  EnterAlways折叠 jetpack compose 折叠工具栏|  退出直到折叠


Spi*_*607 5

我在 Android 文档中发现了这一点,我认为您在问题中链接的文档正在谈论使用嵌套滚动来执行此操作。

val toolbarHeight = 48.dp
    val toolbarHeightPx = with(LocalDensity.current) { toolbarHeight.roundToPx().toFloat() }
    val toolbarOffsetHeightPx = remember { mutableStateOf(0f) }

    val nestedScrollConnection = remember {
        object : NestedScrollConnection {
            override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {

                val delta = available.y
                val newOffset = toolbarOffsetHeightPx.value + delta
                toolbarOffsetHeightPx.value = newOffset.coerceIn(-toolbarHeightPx, 0f)
                return Offset.Zero
            }
        }
    }
    Box(
        Modifier
            .fillMaxSize()

            .nestedScroll(nestedScrollConnection)
    ) {

        LazyColumn(contentPadding = PaddingValues(top = toolbarHeight)) {
            items(100) { index ->
                Text("I'm item $index", modifier = Modifier
                    .fillMaxWidth()
                    .padding(16.dp))
            }
        }
        TopAppBar(
            modifier = Modifier
                .height(toolbarHeight)
                .offset { IntOffset(x = 0, y = toolbarOffsetHeightPx.value.roundToInt()) },
            title = { Text("toolbar offset is ${toolbarOffsetHeightPx.value}") }
        )
    }
Run Code Online (Sandbox Code Playgroud)

  • 只要列表向上或向下滚动,此解决方案就会折叠和展开工具栏。如果您希望工具栏仅在列表滚动到顶部时展开,请参阅@nglauber 答案 (4认同)
  • 感谢这个例子。作为记录,可以在这里找到:https://developer.android.com/reference/kotlin/androidx/compose/ui/input/nestedscroll/package-summary (2认同)