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)。

相关推荐
前端fighter4 小时前
Vue 3 路由切换:页面未刷新问题
前端·vue.js·面试
lskblog4 小时前
使用 PHP Imagick 扩展实现高质量 PDF 转图片功能
android·开发语言·前端·pdf·word·php·laravel
whysqwhw4 小时前
Node-API 学习二
前端
whysqwhw4 小时前
Node-API 学习一
前端
Jenna的海糖4 小时前
Vue 中 v-model 的 “双向绑定”:从原理到自定义组件适配
前端·javascript·vue.js
一碗清汤面4 小时前
打造AI代码审查员:使用 Gemini + Git Hooks 自动化 Code Review
前端·git·代码规范
Sagittarius_A*4 小时前
SpringBoot Web 入门指南:从零搭建第一个SpringBoot程序
java·前端·spring boot·后端
我是ed4 小时前
# Vue 前端封装组件基础知识点
前端
芦苇Z4 小时前
CSS :has() 父级选择器与关系查询
前端·css