当前位置: 首页 > news >正文

Compose 常用UI组件

Compose 常用UI组件

  • 概述
  • Modifier 修饰符
    • 常用Modifier修饰符
      • 作用域限定Modifier
    • Modifier 实现原理
      • Modifier.Element
      • 链的构建
      • 链的解析
  • 常用基础组件
    • 文字组件
    • 图片组件
    • 按钮组件
    • 选择器
    • 对话框
    • 进度条
  • 常用布局组件
    • 线性布局
    • 帧布局
  • 列表组件

概述

Compose 预置了很多基础组件,如 Button,TextField,TopAppBar等,他们都是基于 Material Design规范设计等。同时也提供了 Column,Row,Box等容器组件,每个基础组件都有一个Modifier修饰符。

Modifier 修饰符

允许我们通过连是调用的写法来为组件应用一系列样式设置,如边距,位移,字体等。

常用Modifier修饰符

  • Modifier.size:组件大小
  • Modifier.background: 为组件添加背景色
  • Modifier.fillMaxSize:让组件高度或者宽度上填满父空间
  • Modifier.border & Modifier.padding:给组件添加边框和间隙
  • Modifier.offset:移动被修饰组件的位置,分别传入垂直或水平方向的偏移量

作用域限定Modifier

Compose 的作用域限定实现了 Modifier 的安全调用,我们只能在特定作用域中调用修饰符
如下方 Box 的定义中,BoxScope即是作用域

@Composable
inline fun Box(
    modifier: Modifier = Modifier,                   //修饰符
    contentAlignment: Alignment = Alignment.TopStart,//内容的位置
    propagateMinConstraints: Boolean = false,       //是否应将传入的最小约束传递给内容
    content: @Composable BoxScope.() -> Unit    //内容,即界面元素
) {
    ......
}
  1. matchParentSize:BoxScope中使用,保证当前组件的尺寸与父组件相同
  2. weight:在RowScope或ColumnScope中使用,用于设置百分比

Modifier 实现原理

查看源码,Modifier接口有3个直接实现类或接口:伴生对象Modifier、内部子接口Modifier.Element、CombinedModifier。

  • 伴生对象Modifier:最常用的Modifier, 当我们在代码中使用 Modifier.xxx(),实际使用的就是这个伴生对象。
  • 内部子接口 Modifier.Element:当我们使用Modifier.xxx()时,其内部实际会创建一个Modifier实例。
  • CombinedModifier:Compose内部维护的数据结构,用于连接Modifier链中的每个Modifier结点。

Modifier.Element

  • LayoutModifier:与布局相关,但凡涉及大小的,位置都和这个相关。
  • ComposedModifier: 一个私有类,用户无法直接创建。它主要用于组合多个Modifier实例。
  • DrawModifier:来在布局空间中执行绘制操作,过Modifier.drawWithContent函数创建。
  • …,每个Element都有自己专属的作用。

链的构建

当我们通过链式调用Modifier时,其实调用的是then()方法来拼接Modifier

interface Modifier {
    infix fun then(other: Modifier): Modifier =
        if (other === Modifier) this else CombinedModifier(this, other)
}

class CombinedModifier(
    private val outer: Modifier,
    private val inner: Modifier
) : Modifier

Modifier链结构

链的解析

借助 Modifier 接口中 foldIn() 与 foldOut() 用法,
foldIn():正向遍历Modifier链,SizeModifier-> Background -> PaddingModifier -> ComposedModifier
foldOut():反向遍历 Modifier 链, ComposedModifier -> PaddingModifier -> Background ->SizeModifier
遍历形成的链没有 CombinedModifier,因为CombinedModifier重写了foldIn()方法

interface Element : Modifier {
   ...
    override fun <R> foldIn(initial: R, operation: (R, Element) -> R): R =
        operation(initial, this)
}

class CombinedModifier(
    private val outer: Modifier,
    private val inner: Modifier
) : Modifier {
   ...
    override fun <R> foldIn(initial: R, operation: (R, Modifier.Element) -> R): R =
        inner.foldIn(outer.foldIn(initial, operation), operation) 
}

我们知道很多Compose组件都是基于Layout这个基础组件实现的,所以我们来看看我们创建的Modifier在其中是如何进行传递的。可以发现我们的modifier传入了一个名为materializerOf方法。

@Composable inline fun Layout(
    content: @Composable () -> Unit,
    modifier: Modifier = Modifier,
    measurePolicy: MeasurePolicy
) {
  ...
    ReusableComposeNode<ComposeUiNode, Applier<Any>>(
        factory = ...,
        update = {
      ...
        },
        skippableUpdate = materializerOf(modifier), // 重点
        content = ...
    )
}

走进Composer.materialize()。可以发现源码中使用了fouldIn()方法,进行了递归处理,完全摊开的Modifier链。

fun Composer.materialize(modifier: Modifier): Modifier {
  ...
    val result = modifier.foldIn<Modifier>(Modifier) { acc, element ->
        acc.then(
            if (element is ComposedModifier) {
                @kotlin.Suppress("UNCHECKED_CAST")
                val factory = element.factory as Modifier.(Composer, Int) -> Modifier
                val composedMod = factory(Modifier, this, 0) // 生产 Modifier
                materialize(composedMod) // 生成出的 Modifier 可能也包含 ComposedModifier,递归处理
            } else element
        )
    }
  ...
    return result
}

常用基础组件

文字组件

  • Text:文本组件,如果想脱离Material Design使用,需要用BasicText。
  • SelectionContainer:Text默认是不能长按选择的,此组件对包裹的Text进行选中。
  • TextField:文本输入框,如果想脱离Material Design使用,需要使用BasicTextField

图片组件

  • Icon:用于显示小图标,支持矢量图ImageVector,位图ImageBitmap,画笔Painter
  • Image:用于显示图片。
  • Image和Icon对比,如下参数不同:
  • alignment: 内容对齐方式
  • contentScale: 缩放,类似Android ScaleType
  • alpha: 内容的Alpha通道
  • colorFilter: 色彩过滤器,可以实现tint、滤镜矩阵等,非Compose特有,不再展开

按钮组件

  • Button:Material Design风格按钮,使用 interactionSource监听组件状态的事件源。
  • ImageButton:可点击的图标,一般用于应用中导航,图标默认尺寸 24*24dp

选择器

  • Checkbox:复选框
  • TriStateCheckbox:三态选择器
  • Switch:单选开关
  • Slider:滑竿组件

对话框

  • Dialog:没有show和dismiss,显示隐藏看 Composable 在重组中是否被执行。
  • AlertDialg:警告对话框,是对 Dialog 的封装,遵守 MD 风格。

进度条

  • LinearProgressIndicator:直线进度条
  • CircularProgressIndicator:圆形进度条。

常用布局组件

线性布局

  • Column:用于垂直排列多个组件。
  • Row:用于水平排列多个组件。

帧布局

  • Box:用于在屏幕上创建一个矩形的区域,类似 FrameLayout。
  • Surface:用于绘制一块可交互的区域,用于设置边框,圆角,颜色等。
  • 如果需要快速设置界面形状,阴影,边框,颜色,可用Surface,减少Modifier的使用量
  • 如果只是需要简单设置界面的背景颜色,大小,且需要简单安排里面布局的位置,则用Box更合适。
  • Spacer:留白组件。
  • ConstraintLayout:约束布局,使用 createRefs 和 constrainAs 绑定引用,同时支持Barrier,Guideline,Chain。
  • Scaffold 脚手架,实现了 Material Design 的布局结构,可以方便的构建 TopAppBar,BottomNavigation和侧边栏。

列表组件

  • LazyComposables:包含 LazyColumn 和 LazyRow, 用于垂直 和 水平显示 滚动的列表。
  • LazyListScope作用域:包含 item,item(Int) 和 items(List)以及 itemsIndexed(List),用于构建LazyComposables的列表内容。
  • 在列表中为内容设置外边距,可以使用contentPadding属性。

参考资料:图解Compose Modifier实现原理 ,竟然如此简单!

相关文章:

  • Duplicate entry for key ‘PRIMARY‘ 主键重复报错解决
  • 动态规划
  • Image Downloader下载文章图片的WordPress插件
  • Redis 限流
  • unity获取指定麦克风的分贝(deepseek)
  • DeepSeek 点燃关键技术突破的科技引擎,驶向未来新航道
  • 下拉框的数据置为危险的‘删除‘状态时弹窗确认
  • Jenkins 给任务分配 节点(Node)、设置工作空间目录
  • 2025最新高维多目标优化:基于城市场景下无人机三维路径规划的导航变量的多目标粒子群优化算法(NMOPSO),MATLAB代码
  • 自动化合约生成与管理:AI与Python的完美结合
  • 阿里云通过docker安装skywalking及elasticsearch操作流程
  • `AdminAdminDTO` 和 `userSession` 对象中的字段对应起来的表格
  • 使用最广泛的Web应用架构
  • linux中的查用命令
  • 万字长文解析:深入理解服务端渲染(SSR)架构与全栈实践指南
  • 基于 JavaWeb 的 Spring Boot 网上商城系统设计和实现(源码+文档+部署讲解)
  • [深度学习][python]yolov12+bytetrack+pyqt5实现目标追踪
  • springboot整合 xxl-job
  • Transformer解析——(五)代码解析及拓展
  • Spark 性能优化(四):Cache
  • 网约车座椅靠背张贴“差评者得癌症”,如祺出行:未收到投诉无法处理
  • 中哥两国元首共同见证签署《中华人民共和国政府与哥伦比亚共和国政府关于共同推进丝绸之路经济带和21世纪海上丝绸之路建设的合作规划》
  • 白天气温超30℃的北京,晚间下起了冰雹
  • 多地警务新媒体整合:关停交警等系统账号,统一信息发布渠道
  • 国际博物馆日中国主会场确定,北京将展“看·见殷商”等展览
  • 经济日报金观平:充分发挥超大规模市场优势