主页 > 软件开发  > 

Compose常用UI组件

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 //内容,即界面元素 ) { ...... } matchParentSize:BoxScope中使用,保证当前组件的尺寸与父组件相同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 接口中 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:用于显示文本内容。Image:用于显示图片。Button:用于创建按钮。TextField:用于接收用户输入的文本。Divider:用于在 UI 中添加分隔线。 常用布局组件 Column:用于垂直排列多个组件。Row:用于水平排列多个组件。Box:用于在屏幕上创建一个矩形的区域。Surface:用于绘制一块可交互的区域。Card:用于显示一个卡片式的 UI 元素。Spacer:留白组件。ConstraintLayout:约束布局。Scaffold 脚手架。 列表组件 LazyComposables:包含 LazyColumn 和 LazyRow, 用于垂直 和 水平显示 滚动的列表。LazyListScope作用域:包含 item,item(Int) 和 items(List)以及 itemsIndexed(List),用于构建LazyComposables的列表内容。

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

标签:

Compose常用UI组件由讯客互联软件开发栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“Compose常用UI组件