1.modifier的接口实现
Modifer实际上是一个接口,他有三个具体实现。分别是:一个Modifier伴生对象, Modifier.Element, CombinedModifier。 Modifier伴生对象是我们对Modifier修饰符调用的起点。 CombinedModifier用于链接Modifier链中每个modifier对象。 Modifier.Element代表具体的修饰符。 我们创建的各种Modifier.Element本质上都是一个Modifier.Element.
2.链的构建
Modifier.size()内部会创建一个SizeModifier实例,并使用then进行连接。then返回一个CombinedModifier。这个CombinedModifier就是用来连接两个Modifier.Element.
我们通过Modifier.size(100.dp)这句代码来分析下:
此时,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"
}
来看下Modifier的源码。注意这里伴生对象的then方法。进行了重写,他的then直接返回other。也就是SizeModifier。
接着我们在链上增加.background()来增加背景色。
那么我们来看then()方法怎么连接这两个Modifier.Element。
因为Element本身没有重新then方法。Modifier接口中有个默认实现。我们来看这个实现:
/**
* Concatenates this modifier with another.
*
* Returns a [Modifier] representing this modifier followed by [other] in sequence.
*/
infix fun then(other: Modifier): Modifier =
if (other === Modifier) this else CombinedModifier(this, other)
可以看到这里会返回一个CombinedModifier。
这个CombinedModifier的outer是SizeModifier。inner是Bacground。
接着调用.padding(10.dp)来设置内边距。
此时,padding内部使用的this,还是CombinedModifier。通过then 连接了一个paddigModifier实例。
此时的代码:
modifier = Modifier
.size(100.dp)
.background(Color.Green)
.padding(10.dp)
看他源码:
un Modifier.pointerInput(
key1: Any?,
block: suspend PointerInputScope.() -> Unit
): Modifier = this then SuspendPointerInputElement(
key1 = key1,
pointerInputHandler = block
)
发现仍然是then进行连接。无论链路有多长,都可以分析。