本文译自 Android Developers Blog: What’s new in the Jetpack Compose March ’23 release,由 FunnySaltyFish 和 ChatGPT 共同完成

Jetpack Compose 上新:Pager、跑马灯、FlowLayout

2023年3月底,Google 正式发布 Jetpack Compose 的 1.4 版别,它是 Android 的现代原生 UI 工具包。此版别包含新功用,如 Pager 和 Flow Layouts,以及文本款式的新办法,例如连字号和换行行为。它还提高了修饰符的功用并修正了许多过错。

Pager 支撑

在 1.4 版别之前,运用 Pager 需要凭借 accompanis 库。如今,Pager 终于被纳入了 Jetpack Compose 根底库中中。它可完成与 View 中的 ViewPager 相似的功用。在 API 规划上,Pager 相似于 LazyColumn,运用起来十分简洁

// 显现 10 个项目
HorizontalPager(pageCount = 10) { page ->
  // 每一页的内容,比方显现个文本
  Text(
    text = "Page: $page",
    modifier = Modifier.fillMaxWidth()
   )
}

总的来说,新的 Pager 基本承继了原先 Accompanist 的 API,只是个别参数有点改动(比方 count -> pageCount)。而关于 Indicator(指示器),仍然能够直接用 accompanist/pager-indicators,最新版已经对 Jetpack Compose 1.4 的 Pager 做了适配。

比方下面这个简易的带 Tab 指示器的横向 Pager 比方:

@Composable
fun HorizontalPagerWithIndicator() {
  val pagerState = rememberPagerState()
​
  TabRow(
    // Our selected tab is our current page
    selectedTabIndex = pagerState.currentPage,
    // Override the indicator, using the provided pagerTabIndicatorOffset modifier
    indicator = { tabPositions ->
      TabRowDefaults.Indicator(
        Modifier.pagerTabIndicatorOffset(pagerState, tabPositions)
       )
     }
   ) {
    // Add tabs for all of our pages
    pages.forEachIndexed { index, title ->
      Tab(
        text = { Text(title) },
        selected = pagerState.currentPage == index,
        onClick = { /* TODO */ },
       )
     }
   }
​
  HorizontalPager(
    pageCount = pages.size,
    state = pagerState,
   ) { page ->
    Text(
      text = "Page $page",
      style = MaterialTheme.typography.h5,
      modifier = Modifier
         .fillMaxSize()
         .wrapContentSize(Alignment.Center),
      textAlign = TextAlign.Center,
     )
   }
}

作用如下:

Jetpack Compose 上新:Pager、跑马灯、FlowLayout

要查看更多的 Pager 比方,或者想把 Accompanist 完成搬迁到新版,请查看搬迁攻略。更多内容,请参阅Pager 的文档。

Flow Layout

Flow Layout 包含 FlowRowFlowColumn ,当一行(或一列)放不下里边的内容时,会自动换行。这些流式布局还允许运用权重进行动态调整巨细,以将项目分配到容器中。

以下是一个完成房地产应用程序过滤器列表的示例:

Jetpack Compose 上新:Pager、跑马灯、FlowLayout
@Composable
fun Filters() {
 val filters = listOf(
  "Washer/Dryer", "Ramp access", "Garden", "Cats OK", "Dogs OK", "Smoke-free"
  )
 FlowRow(
  horizontalArrangement = Arrangement.spacedBy(8.dp)
  ) {
  filters.forEach { title ->
   var selected by remember { mutableStateOf(false) }
   val leadingIcon: @Composable () -> Unit = { Icon(Icons.Default.Check, null) }
   FilterChip(
    selected,
    onClick = { selected = !selected },
    label = { Text(title) },
    leadingIcon = if (selected) leadingIcon else null
    )
   }
  }
}

FlowRowcontentRowScope 接收器,这意味着 RowScope 的一些特有 Modifier 也能够在这里运用,比方 weight

修正 Modifier 中的功用问题

咱们在 10 月份版别中开端了一个严重的内部 Modifier 重构作业,将多个根底 Modifier 搬迁到新的 Modifier.Node 架构中。这包含 graphicsLayer、更低层级的焦点修改器、padding、offset 等等。这个重构应该会带来这些 API 的功用改善,而且您不需要更改代码即可取得这些好处。这项作业仍在继续,咱们预计在未来的发布中将 Modifiers 搬迁到 ui 模块之外,从而取得更多收益。了解更多关于该改变背面原理的信息,请观看ADS演讲 “深入 Compose Modifiers”。

增强 Text 和 TextField 的灵活性

除了各种功用改善、API稳定性和 bug 修正之外,compose-text 1.4 发布还支撑最新的emoji版别,包含向后兼容旧版 Android 。支撑此功用无需更改应用程序。如果您正在运用自定义emoji处理方案,请查看 PlatformTextStyle(emojiSupportMatch)

另外,咱们还处理了运用 TextField 时的首要痛点之一。在某些情况下,在可滚动的 Column 或 LazyColumn 中的文本字段在被聚集后可能会被屏幕键盘遮挡。咱们重新规划了滚动和聚集逻辑的中心部分,并增加了一些要害 API,如 PinnableContainer 来处理这个问题。

最后,咱们为 Text 及其 TextStyle 增加了许多新的自定义选项:

  • 运用 TextStyle.drawStyle 绘制分级显现的文本
  • 运用 TextStyle.textMotion 改善动画过程中的文本过渡和易读性
  • 运用 TextStyle.lineBreak 装备换行行为。运用内置语义装备(如标题、阶段或简单),或运用所需的策略、严厉性和分字符值构建您自己的换行符装备。
  • 运用 TextStyle.hyphens 增加断字支撑
  • Text 和 TextField 中可运用 minLines 参数定义可见行的最小数量
  • 经过应用 basicMarquee 修饰符打造出跑马灯作用。顺带,由于这是一个修饰符,你能够把它应用于任何 Composable!
  • Jetpack Compose 上新:Pager、跑马灯、FlowLayout
    运用概括的选框文本,并运用 drawStyle API 在其上标记形状。

Jetpack Compose 上新:Pager、跑马灯、FlowLayout

这张图 webp 压缩的有点问题,能够去文末的代码库房实在跑一下

中心功用的改善和修正

为了呼应开发人员的反应,咱们在中心库中供给了一些特别受欢迎的功用和过错修正:

  • Test waitUntil 现在接受 Matcher!能够运用此 API 轻松地在特定条件下将测试与 UI 同步
  • animatedContent 现在正确支撑中止并返回到其以前的状况。
  • 无障碍服务焦点次序已得到改善:在常见情况下,例如顶部/底部栏,次序现在更合乎逻辑
  • 如果你供给了一个可选的 onReset lambda,则 AndroidView 能够在 LazyList 中被重用。此改善允许您在 LazyList 中运用杂乱的非 Composable 的 View。(!!!)
  • Color.lerp 功用已得到改善,现在执行零分配:由于此办法在淡入淡出动画期间以高频率调用,因而这应该能够减少废物收回暂停的数量,尤其是在较旧的 Android 版别上。
  • 许多其他非必须 API 和过错修正作为惯例整理的一部分。有关详细信息,请参阅发行说明。

本文的部分代码已上传至:FunnySaltyFish/JetpackComposeStudy,可在库房下载 demo 直接运转

本文正在参加「金石方案」