Android Jetpack Compose基础一之Modifier
Modifier的调用顺序
Modifier的调用顺序会影响ui的效果,不同的调用顺序会产生不同的Modifier链,Modifier是一个接口,它有三个具体实现:
1.伴生对象Modifier
伴生对象的Modifier是所有链式调用的起点
companion object : Modifier {
override fun <R> foldIn(initial: R, operation: (R, Element) -> R): R = initial
override fun <R> foldOut(initial: R, operation: (Element, R) -> R): R = initial
override fun any(predicate: (Element) -> Boolean): Boolean = false
override fun all(predicate: (Element) -> Boolean): Boolean = true
override infix fun then(other: Modifier): Modifier = other
override fun toString() = "Modifier"
}
2.Modifier.Element 代表具体的修饰符
例如LayoutModifier等具体的表现是实现了Element
interface Element : Modifier {
override fun <R> foldIn(initial: R, operation: (R, Element) -> R): R =
operation(initial, this)
override fun <R> foldOut(initial: R, operation: (Element, R) -> R): R =
operation(this, initial)
override fun any(predicate: (Element) -> Boolean): Boolean = predicate(this)
override fun all(predicate: (Element) -> Boolean): Boolean = predicate(this)
}
3.CombinedModifier用于连接Modifier链中的每个Modifier
class CombinedModifier(
internal val outer: Modifier,
internal val inner: Modifier
) : Modifier {
override fun <R> foldIn(initial: R, operation: (R, Modifier.Element) -> R): R =
inner.foldIn(outer.foldIn(initial, operation), operation)
override fun <R> foldOut(initial: R, operation: (Modifier.Element, R) -> R): R =
outer.foldOut(inner.foldOut(initial, operation), operation)
override fun any(predicate: (Modifier.Element) -> Boolean): Boolean =
outer.any(predicate) || inner.any(predicate)
override fun all(predicate: (Modifier.Element) -> Boolean): Boolean =
outer.all(predicate) && inner.all(predicate)
override fun equals(other: Any?): Boolean =
other is CombinedModifier && outer == other.outer && inner == other.inner
override fun hashCode(): Int = outer.hashCode() + 31 * inner.hashCode()
override fun toString() = "[" + foldIn("") { acc, element ->
if (acc.isEmpty()) element.toString() else "$acc, $element"
} + "]"
}
Modifier链的形成过程
1、设置size
Modifier.size(10.dp)
实际调用的是伴生对象的Modifiert.then(SizeElement())方法
infix fun then(other: Modifier): Modifier =
if (other === Modifier) this else CombinedModifier(this, other)
输出结果为
CombinedModifier(Modifier,SizeElement())
2、设置background
Modifier.size(10.dp).background(Color.Green)
实际调用的是
CombinedModifier(Modifier,SizeElement()).then(BackgroundElement())
输出的结果为
CombinedModifier(CombinedModifier(Modifier,SizeElement()),BackgroundElement())
Modifier链的解析过程
绘制ui时,会遍历Modifier链上配置信息,Compose使用:
1、foldout正向遍历(SizeElement-》BackgroundElement)
2、foldin进行反向遍历(BackgroundElement-》SizeElement)
override fun <R> foldIn(
initial: R, //折叠计算的初始值
operation: (//具体计算方法
R,
Modifier.Element) -> R): R //Modifier.Element当前遍历到的Modifier,R表示当前计算的返回结果
=inner.foldIn(outer.foldIn(initial, operation), operation)
override fun <R> foldOut(initial: R, operation: (Modifier.Element, R) -> R): R =
outer.foldOut(inner.foldOut(initial, operation), operation)