modifier: Modifier = Modifier 的用法
Google 引荐在自界说一个Compose的时分,第一个有默认参数值的类型 要用 modifer ,例如:
有人可能会问为啥要这样引荐呢,由于第一个有默认参数类型的 参数 在实际调用的时分 能够不写 xxx=yyy
便是让调用者方便一点 仅此而已, 接着看上面红框中的代码 ,有人觉得 这个代码好古怪啊
由于我点进去今后 发现这个Modifier是一个目标啊,目标也能够做参数类型了?
仔细看看,其实不然
这个Modifier实质上 他首要是一个接口,在这个接口之中,咱们界说了一个
companion object : Modifier
Modifier的伴生目标,留意这个目标是完成了Modifier接口的,仅仅这个目标名字和interface的名字一样。
这个语法糖在很多当地都有调用,比方kotlin的协程中 就有这个东西,有爱好的能够自己看一下,
所以再看一下这个写法:
第一个参数是接口,默认值是一个名为Modifier的半生目标 他完成了Modifer 这个接口
如何了解Modifier的链式调用
看下面这行代码
Modifier.background(Color.Green)
咱们点进去看今后能够得到下图:
通过这张图,咱们能够得到如下若干个信息
1.backgroun是Mofifer接口的一个扩展函数 2.这个扩展函数实质上 是调用了Modifier这个接口的then办法 3.这个then办法的参数 是Background这目标
咱们首要来看 Modifier这个接口的then 办法是个啥
能够看出来这个then办法实质上便是 A.then(B)
假如这个B是Modifier这个伴生目标 那么就回来A 假如不是 则 把AB 组合起来
留意这个是Modifier这个接口的 then办法完成, 但是回到咱们末节开头的办法调用
Modifier.background(Color.Green)
这儿实质是啥? 是用的Modifier这个伴生目标,所以 这儿要看的是Modifier这个伴生目标的then办法完成
那他的完成便是
那么明显 Modifer.background 这个调用 就等于 Modifier then (Background) 一起他的回来值也是 Background这个目标
这儿一定要搞清楚 不然后面是无法了解Modifer链式调用的
一起咱们也能猜到了 这个Background也一定完成了Modifier这个接口
同样
Modifier.background(Color.Green).then(Modifier.padding(10.dp))
看上面这个代码, 等价于
CombinedModifier(Modifier.background(Color.Green),Modifier.padding(10.dp))
为什么?
由于Modifier.background 回来的是一个Background的Modifier,他的then办法便是接口Modifer里边的then办法 最终会走到 CombinedModifier 办法
到这儿,能够下一个定论,在整个Compose的体系中, Modifier 只要三种
- CombinedModifier ,他的作用便是能够装载n个Modifier 放到一起
- Modifier接口内界说的名为Modifier的伴生目标
- 完成了Element这个接口的 Modifier
ComposedModifier
这是一个特别的Modifier,专门用一个末节来了解一下 能够看下这个界说,一个private的class 咱们无法直接调用
看下用法的作用差异:
// 这个写法代表 代码执行到这儿 就立即创立一个padding作用的Modifier
Modifier.padding(10.dp)
// 这个写法代表 传进去了一个lambda表达式,等到真实需求用到的时分才会创立这个padding作用的Modifier
Modifier.composed { Modifier.padding(10.dp) }
有人要问了,真实需求用到的时分才创立是啥意思?,能够近似的了解为layout的时分才创立
能够跟一下代码
代码全体上并不难分析,最终便是落到 materialize 这个函数里边
能够看到里边其实便是一个循环,在循环的时分判断 假如是ComposedModifier 那就创立出来一个真实的Modifier目标
到这儿是不是又懵了,这样做到底有啥特别作用呢? 我直接在Box创立的时分就直接弄一个Modifier出来不行吗
比方说下面这2个写法,实质上 除了创立modifer的机遇不同,其他在展示作用上一摸一样的
能够看一下下面这个比如
Column() {
val modifier1 = Modifier.composed {
var size by remember {
mutableStateOf(100.dp)
}
Modifier
.size(size)
.background(Color.Red)
.clickable {
size = 5.dp
}
}
var size by remember {
mutableStateOf(100.dp)
}
val modifier2 = Modifier
.size(size)
.background(Color.Blue)
.clickable {
size = 5.dp
}
Box(modifier1)
Box(modifier1)
Box(modifier2)
Box(modifier2)
}
代码很简单,其实便是4个box, 2个红色的box 用的是ComposdModifier的写法,2个蓝色的Box用的是传统的写法,点击事情都是 点击了今后size变小, 那么这两种写法 在这种场景下就有实质的差异了。
首要看红色的box,由于他们用的是ComposdModifier,在layout的时分才会进行调用,每次调用 都会创立出不同的Modifier目标,所以当你点击其间一个红Box的时分,只要那个被点击的红Box才会尺寸变小,另外一个是不会变小的,
而蓝色的box 则不同,由于你是在创立Column的时分就创立好的Modifer,2个蓝色的box实质上用的仍是一个Modifer目标,所以这2个蓝色的Box 你随便点其间的一个,这2个会一起变小
有了这个差异,咱们就很简单能够得到这个ComposedModifier的主要应用场景: 当你需求对外提供一个带状况的Modifier的时分,就能够考虑 运用ComposedModifier
例如:
// 对外暴露 一个公共的Modifer,而且这个Modifier是带状况的
//
fun Modifier.sizeChange() = composed {
var size by remember {
mutableStateOf(100.dp)
}
//LaunchedEffect(key1 = , block = )
//LocalContext
Modifier
.size(size)
.background(Color.Red)
.clickable {
size = 5.dp
}
}