type
status
date
slug
summary
tags
category
password
icon
😀
21年的时候就简单了解过 Compose,碍于工作被带偏,一直没有机会实践和学习。有幸得到同事提醒,一起参加国内首个免费的 Compose UI 系列 Codelab,比较匆忙,决定学习了解

布局

简单的布局组件

  • Row:横向布局
  • Column:纵向布局
  • Box:层叠布局

约束布局

引用是使用 createRefs( 或 createRefFor() 创建的,ConstraintLayout 中的每个可组合项都需要有与之关联的引用。 约束条件是使用 constrainAs() 修饰符提供的,该修饰符将引用作为参数,可让您在主体lambda 中指定其约束条件。约束条件是使用 linkTo 或其他有用的方法指定的。parent 是一个现有的引用,可用于指定对 ConstraintLayout 可组合项本身的约束条件。
解藕 API 在某些情况下,最好将约束条件与应用它们的布局分离开来,例如我们可能会希望根据屏幕配置来更改约束条件,或在两个约束条件集之间添加动画效果
  • ConstraintSet 作为参数传递给 ConstraintLayout
  • 使用 layoutid 修饰符将在 ConstraintSet 中创建的引用分配给可组合项

Intrinsics

Compose 只测量子元素一次,测量两次两次会引发运行时异常,但是,有时在测量子元素之前,我们需要一些有关子元素的信息 Intrinsics 允许在实际测量之前查询子项
  • (min|max)IntrinsicWidth:鉴于此宽度,正确绘制内容的最小 / 最大宽度是多少
  • (min|max)IntrinsicHeight:鉴于此高度,正确绘制内容的最小 / 最大高度是多少
 

一些常用的组件

  • slots api: 插槽,类似 vue 的 slots,常使用的顶级组件有 Scaffold,常用组件有TopAppBar、 BottomAppBar、 Floating、ActionButton 和 Drawer
  • List
    • Column 和 Row 也可以实现List的效果
      • LazyColumn 和 LazyRow 如果需要指定滑动位置,需要手动设置 scrollState

      自定义布局

      在 Compose 中,界面元素由可组合函数表示,此类函数在被调用后会发出一部分界面,这部分界面随后会被添加到呈现在屏幕上的界面树中。每个界面元素都有一个父元素,还可能有多个子元素。此外,每个元素在其父元素中都有一个位置,指定为 (x,y) 位置;也都有一个尺寸,指定为 width 和 height。

      布局修饰符

      您可以使用 layout 修饰符来修改元素的测量和布局方式。Layout 是一个 lambda;它的参数包括您可以测量的元素(以 measurable 的形式传递)以及该可组合项的传入约束条件(以 constraints 的形式传递)。
      软键盘
      • keyboardOptions:用于启用显示万册 IME 操作
      • keyboardActions:当指定 IME 操作被触发后需要执行的行为。

      Compose 状态

      非结构化状态: 在传统的 Android 开发中,开发者常常是初始化好页面后,每次到达一个状态,就手动将上一个状态修改到新的状态,这种并没有对状态进行一个结构化的管理。可能会出现几个问题:
      • 测试:由于 UI 的状态与 Views 代码交织在一起,造成测试困难
      • 部分状态的更新:当屏幕有更多的事件时,很容易忘记更新部分状态以响应事件。因此用户可能会看到不一致或不正确的 UI。
      • 部分 UI 更新:每次状态更改后手动更新 UI,因此有时候很容易忘记这一点,因此,用户可能看到陈旧的数据。
      • 代码复杂性:在这种模式下编码时很难提取一些逻辑,结果代码有变得难以阅读和理解的趋势。
      为了解决非结构化状态带来的问题,Android 通过 LiveDate 和 LifeCycle 实现了单项数据流的方式,
      单项数据流是一种状态乡下流动而事件向上流动的设计,他的优势有:
      • 可测试性:通过将状态与显示他的 UI 分离,可以更轻松地测试 ViewModel 和Activity。
      • 状态封装:因为状态只能在一个地方(the viewModel)更新,随着 UI 的增长,你不太可能引入部分状态更新错误。
      • UI 一致性:所有的状态更新都痛使用可观察状态持有者立即反应在 UI 中。
      状态提升
      如果可组合项时无状态的,那它如何才能显示可修改的列表?为实现此目的,我们会使用一种称为状态提升的技术。
      Compose 中的状态提升是一种将状态移至可组合项的调用方,以使可组合项无状态的模式。无状态组件更容易测试,往往有更少的错误,并提供更多的重用机会。
      💡
      上面的 TodoScreen 组件内部是没有状态的,他的数据是外部传入的 items,所谓的状态提升就是自己只负责展示数据,具体数据怎么来怎么变,我不关心,外部传给我什么数据我就按照自己的方式展示。
      事实证明,这些参数的组合使得调用方能够从此可组合项中提升状态,为了了解具体的工作原理,我们来探索此可组合项的界面更新循环
      • 事件:当用户请求添加或删除时,TodoScreen 会调用 onAddItem 或 onRemoveItem
      • 更新状态:TodoScreen 的调用方可以通过更新状态来响应这些事件
      • 显示状态:状态更新后,系统将使用新的 items 再次调用 TodoScreen,而且后者可以在界面上显示它们
      调用方负责确定保持此状态的位置和方式,不过,他可以合理地存储 items,例如,存储在内存中或从 Room 数据库中读取。TodoScreen 与状态的管理方式时完全解藕的。
      应用与可组合项时,这通常意味着向可组合项引入两个参数
      • value:T - 要显示的当前值
      • onValueChange: (T) → Unit - 请求更改值的事件,其中T是建议的新值。

      Compose状态管理

      重组

      在命令式界面模型中,如果需要更改某个组件,可以在该组件上调用 setter 以更改其内部状态。在 Compose 中,可以使用新数据再次调用可组合函数。这样会导致函数进行重组———系统会根据新数据重新绘制组件。Compose 框架可以智能地仅重组已更改的组件。

      remember

      将内存引入可组合函数
      remember 提供了可组合函数内存
      系统会将 remember 计算的值存储在组合树中,而且只有当 remember 的键发生变化时,才会重新计算该值。
      可以将 remember 看作是函数为单个对象提供的存储空间,过程与 private val 属性在对象中执行的操作相同
      notion image
      有状态和无状态
      使用 remember 存储对象的可组合项会创建内部状态,使该可组合项有状态
      在调用方不需要控制状态,并且不必自行管理状态便可使用状态的情况下,“有状态”会非常有用,但是,具有内部状态的可组合项往往不易重复使用,也更难测试。
      无状态可组合项是指不保存任何状态的可组合项。实现无状态的一种简单方法是使用状态提升

      MutableState

      val (value, setValue) = remember { mutableStateOf("") }
      这个函数通过 remember 给自己添加内存,然后在内存中存储一个 mutableStateOf 创建的MutableStateOf<String> 对象,它提供一个可观察状态容器,是 Compose 内置的类型
      对 value 的任何更改动将自动重新组合读取此状态的任何可组合函数。
      可以通过以下 MutableState 三种声明一个可组合对象:
      • val state = remember{ mutableStateOf(default) }
      • var value by remember { mutableStateOf(default) }
      • val (value, setValue) = remember { mutableStateOf(default) }
      在组合中创建 State<T>(或其他有状态对象)时,务必对其执行 remember 操作,否则每次重组时他将重新初始化。
      MutableState<T> 类似于 MutableLiveData<T>,但与 Compose 运行时集成,由于他是可观察的,它会在更新时通知 Compose。
      notion image

      Compose 的状态恢复

      rememberSaveable 恢复状态

      在重新创建 activity 或进程后,我们可以使用 rememberSaveable 恢复界面状态,rememberSaveable 可以在重组后保持状态,此外,rememberSaveable 也可以重新创建activity 和进程后保持状态。

      存储状态的方式

      添加到 Bundle 的所有数据类型都会自动保存,如果要保存无法添加到 Bundle 的内容,有以下几种选择:
      • Parcelize:最简单的解决方案是对象添加 @Parcelize 注解,对象将变成可序列化状态,并且可以捆绑。
      • MapSaver:如果上一个方式不适合,可以使用 mapSaver 定义自己的规则,规定如何将对象转换为系统可以保存到 Bundle 的一组值
      • listSaver:未来避免需要为映射定义键,可以使用 listSaver 并将其索引用作键

      CompositionLocal

      显示传参隐式传参
      notion image
      通常情况下,在 Compose 中,数据以参数的形式向下流经整个界面树传递给每个可组合函数。但是对于广泛使用的常用数据(如颜色或类型样式),这可能会很麻烦。
      未来支持无需将颜色作为显示参数依赖项传递给大多数可组合项,Compose提供了CompositionLocal,可创建以树为作用域的具名对象,这可以用作数据流经界面树的一种隐式方式
      可以通过 MaterialTheme 的 colorScheme,shape 和 typography 属性访问的LocalColorScheme,LocalShapes 和 LocalTypography 属性。
      notion image
      如果需要为 CompositionLocal 提供新值,请使用 CompositionLocalProvider 及其 provides infix 函数。
      CompositionLocal 的 current 值对应于该组合部分中的某个祖先提供的最接近的值。

      MaterialTheme

       

      创建 CompositionLocal

      • compositionLocalOf
      如果更改提供的值,只会使读取其 current 值的组件发生重组。
      • staticCompositionLocalOf
      与 compositionLocalOf 不同,staticCompositionLocalOf 更改值会导致提供 CompositionLocal 的整个 content lambda 被重组,而不仅仅是在组合中读取 current 值的组件
      如果为 CompositionLocal 提供的值发生更改的可能性微乎其微或永远不会更改,使用staticCompositionLocalOf 可提高性能
       

      主题

      Material Design 是什么

      Material Design 是一个用于创建数字界面的综合设计体系,Material Design 组件(按钮、卡片、开关等)建立在 Material Theming 之上, Material theme 包括颜色、排版和形状属性.

      Compose 与 Materail Deign 的关系

      如何使用 Material Design

      定义主题

      使用颜色

      处理文本

      如果我们需要对一段文本应用多种样式,可以使用 AnnotatedString 类来应用标记,从而为一系列文本添加 SpanStyle。

      使用形状

       
       
       
       
      Compose-进阶Adb-常用命令
      Loading...
      shuouyang
      shuouyang
      android开发 ReactNative开发 小程序开发
      最新发布
      AOSP 环境搭建
      2025-3-29
      View 绘制流程-源码解析
      2025-3-12
      HTTP
      2025-3-4
      JVM 虚拟机
      2025-2-28
      蓝牙-BLE-基础
      2025-2-28
      从 OkHttp 的原理来看 HTTP
      2025-2-19
      公告
      🎉热点信息🎉
      --- 1 ---
      Jet Brains 推出新的跨平台支持 Kotlin MultiPlatform
      --- 2 ---
      新的小巧便捷的依赖注入框架 Koin
      --- 3 ---
      新一代 API 查询语言 GraphQL