android 如何在向Material3 TopAppBar添加其他内容时保留色调颜色

col17t5w  于 2023-06-20  发布在  Android
关注(0)|答案(2)|浏览(186)

我正在使用Jetpack Compose和Material3开发Android应用程序。
我有一个由TopAppBarLazyColumn组成的屏幕作为内容,通过scrollBehavior链接在一起以实现漂亮的材质色调高度变化:

我现在想添加一个过滤器布局,它应该看起来和感觉像它的顶部应用程序栏的一部分

  • 它应该是粘性的
  • 应该具有相同的音调高度

我的简单实现没有做到这一点:滤波器没有音调升高:

  1. @Composable
  2. fun TestScreen() {
  3. val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()
  4. Scaffold(
  5. topBar = {
  6. Column {
  7. TopAppBar(
  8. title = { Text("Material3 top app bar") },
  9. scrollBehavior = scrollBehavior,
  10. )
  11. Text(
  12. text = "Filter - Filter - Filter - Filter - Filter",
  13. modifier = Modifier
  14. .fillMaxWidth()
  15. .height(30.dp)
  16. )
  17. Divider()
  18. }
  19. },
  20. modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection)
  21. ) { contentPadding ->
  22. LazyColumn(Modifier.padding(contentPadding)) {
  23. items(100) { index ->
  24. Text(
  25. text = "item $index",
  26. modifier = Modifier.fillMaxWidth()
  27. )
  28. }
  29. }
  30. }
  31. }

那么我该如何正确地做到这一点呢?可悲的是,与Material2不同,我找不到“空”的TopAppBar。

inkz8wg9

inkz8wg91#

您好,您可以使用此代码自定义工具栏:

  1. @OptIn(ExperimentalMaterial3Api::class)
  2. @Composable
  3. fun TestScreen() {
  4. val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()
  5. Scaffold(
  6. topBar = {
  7. Column {
  8. TopAppBar(
  9. title = { Text("Material3 top app bar") },
  10. scrollBehavior = scrollBehavior,
  11. )
  12. val colorTransitionFraction = scrollBehavior.state.overlappedFraction
  13. val fraction = if (colorTransitionFraction > 0.01f) 1f else 0f
  14. val appBarContainerColor by animateColorAsState(
  15. targetValue = lerp(
  16. MaterialTheme.colorScheme.surface,
  17. MaterialTheme.colorScheme.surfaceColorAtElevation(3.dp),
  18. FastOutLinearInEasing.transform(fraction)
  19. ),
  20. animationSpec = spring(stiffness = Spring.StiffnessMediumLow), label = ""
  21. )
  22. Text(
  23. text = "Filter - Filter - Filter - Filter - Filter",
  24. modifier = Modifier
  25. .fillMaxWidth()
  26. .height(30.dp)
  27. .background(appBarContainerColor)
  28. )
  29. }
  30. },
  31. modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection)
  32. ) { contentPadding ->
  33. LazyColumn(Modifier.padding(contentPadding)) {
  34. items(100) { index ->
  35. Text(
  36. text = "item $index",
  37. modifier = Modifier.fillMaxWidth()
  38. )
  39. }
  40. }
  41. }
  42. }
展开查看全部
eulz3vhy

eulz3vhy2#

Amiir Kalantari提供了一个漂亮的答案:)
这个答案建立在他的代码上,使其可重用并包括正确的导入。所有的赞美都归于他,因为他弄清楚了困难的部分!

  1. import androidx.compose.animation.animateColorAsState
  2. import androidx.compose.animation.core.FastOutLinearInEasing
  3. import androidx.compose.animation.core.Spring
  4. import androidx.compose.animation.core.spring
  5. import androidx.compose.foundation.background
  6. import androidx.compose.material3.MaterialTheme
  7. import androidx.compose.material3.TopAppBarScrollBehavior
  8. import androidx.compose.material3.surfaceColorAtElevation
  9. import androidx.compose.runtime.getValue
  10. import androidx.compose.ui.Modifier
  11. import androidx.compose.ui.composed
  12. import androidx.compose.ui.graphics.lerp
  13. import androidx.compose.ui.unit.dp
  14. // modelled after https://stackoverflow.com/a/76475561/12871582
  15. public fun Modifier.topAppBarBackground(
  16. scrollBehavior: TopAppBarScrollBehavior,
  17. ): Modifier = composed {
  18. val colorTransitionFraction = scrollBehavior.state.overlappedFraction
  19. val fraction = if (colorTransitionFraction > 0.01f) 1f else 0f
  20. val appBarContainerColor by animateColorAsState(
  21. targetValue = lerp(
  22. MaterialTheme.colorScheme.surface,
  23. MaterialTheme.colorScheme.surfaceColorAtElevation(3.dp),
  24. FastOutLinearInEasing.transform(fraction)
  25. ),
  26. animationSpec = spring(stiffness = Spring.StiffnessMediumLow), label = ""
  27. )
  28. background(appBarContainerColor)
  29. }
展开查看全部

相关问题