Compose 延迟布局

Lazy layouts in Compose

了解如何在 Compose 中制作滚动列表,以及这样为什么比使用 RecyclerView 更简单。了解为什么不允许嵌套滚动列表、如何采用不同方式实现嵌套、为什么列表项的大小绝不能为 0 像素、为什么提供唯一的键非常重要,以及项动画如何运作。最后,您将探索如何显示网格、使用自定义布局管理器,以及了解如何优化性能以提高滚动速度。

1. Lazy Lists

  • LazyColumn
  • LazyRow
  • Lazy grids

Lazy Lists 中可以添加一个 item,也可以添加多个 item。

给 contentPadding 传入 PaddingValues 为 Lazy lists 设置内边距。这个内边距不会缩减 items 的显示区域。

使用 horizontalArrangement 给 LazyRow 设置 item 与 item 之间的间距。其他 Lazy lists 类似。使用 Arrangement.spacedBy() 可以自定义间距。

LazyListState 存储滚动位置还有列表的一些实用信息。

实现点击底部按钮使列表滚动到顶部。

2. Lazy Grids

  • LazyVerticalGrid
  • LazyHorizontalGrid

可以同时设置垂直方向和水平方向的 item 间距。

LazyGridState 和 LazyListState 具有相同的作用。

3. Lazy Layout

Item animations

传入 Modifier.animateItemPlacement() 即可使用动画。

一定要为 item 提供 key,以便找到被移动元素的新位置,item 内的记忆状态也会一起移动。

传入的 key 类型一定是 Bundle 支持的类型,比如基础类型、枚举、Parcelable 等等。其作用是创建 Activity 时保留相应状态。

4. Useful Tips

4.1 Don't use 0-pixel sized item

不要使用大小为 0 像素的 item。因为 item 大小为 0,Lazy Layout 会组合它所有的 item。

4.2 Avoid nesting components scrollable in the same direction

避免嵌套可向同一方向滚动的组件。

仅适用于没有预定义尺寸的子级组件嵌套在可向同一方向滚动的另一个父级组件中。

嵌套不同滚动方向的组件是允许的。

子级组件有预定义尺寸也可以嵌套。

4.3 Beaware of putting multiple elements in one item

注意将多个元素放入一个 item 中的情况。

  • 元素无法单独组合,作为一个整体组合。
  • 会干扰 scrollToItem 和 animateScrollToItem

scrollToItem(2) 会使 Item(3) 显示在顶部。

  • 也有一些将多个元素放入同一个 item 的有效用例,比如在一个列表内添加多个分割线。不希望分割线更改滚动索引,因此分割线不应该作为一个独立元素。而且分割线的尺寸很小,不会影响性能。

  • Consider using custom arrangements 考虑使用自定义排列方式

列表元素不足够填充整个屏幕,但是需要在列表底部展示 Footer。需要自定义 verticalArrangement。

kotlin 复制代码
/**
 * Vertically places the layout children.
 *
 * @param totalSize Available space that can be occupied by the children, in pixels.
 * @param sizes An array of sizes of all children, in pixels.
 * @param outPositions An array of the size of [sizes] that returns the calculated positions
 *   relative to the top, in pixels.
 */
fun Density.arrange(totalSize: Int, sizes: IntArray, outPositions: IntArray)

5. Performance

只有在发布模式下运行且启用了 R8 优化时,才能可靠地衡量延迟布局的性能。

6. Optimization

6.1 Reusing

重复使用组合。

不需要丢弃 item 并启动全新组合可以节省一些时间。

重复使用布局节点。

为不同类型的 item 设置 contentType,Compose 只能在相同类型的 item 之间重复使用组合。

6.2 Prefetching

预提取

当无需处理任何新项的情况下滚动时。

如果有新项进入屏幕,将需要完成更多的步骤。

这样可能会导致渲染有延迟,导致卡顿,也就是掉帧。

我们可以提前准备这些工作(Compose、Measure),在 UI 线程空闲时候完成下一帧的组合和测量(Compose、Measure)。

相关推荐
A923A7 分钟前
【从零开始学 React | 第四章】useEffect和自定义Hook
前端·react.js·fetch·useeffect
ZC跨境爬虫11 分钟前
批量爬取小说章节并优化排版(附完整可运行脚本)
前端·爬虫·python·自动化
ZC跨境爬虫13 分钟前
海南大学交友平台登录页开发实战day4(解决python传输并读取登录信息的问题)
开发语言·前端·python·flask·html
来一颗砂糖橘16 分钟前
pnpm:现代前端开发的高效包管理器
前端·pnpm
前端摸鱼匠17 分钟前
Vue 3 的defineProps编译器宏:详解<script setup>中defineProps的使用
前端·javascript·vue.js·前端框架·ecmascript
木斯佳18 分钟前
前端八股文面经大全: 美团财务科技前端一面 (2026-04-09)·面经深度解析
前端·实习面经·前端初级
LIO21 分钟前
React 零基础入门,一篇搞懂核心用法(适合新手)
前端·react.js
TeamDev35 分钟前
JxBrowser 8.18.2 版本发布啦!
java·前端·跨平台·桌面应用·web ui·jxbrowser·浏览器控件
netkiller-BG7NYT36 分钟前
yoloutils - Openclaw Agent Skill
前端·webpack·node.js
北城笑笑40 分钟前
FPGA 51,基于 ZYNQ 7Z010 的 FPGA 高速路由转发加速系统架构设计(Xilinx ZYNQ-MINI 7Z010 CLG400 -1)
前端·fpga开发·系统架构·fpga