modifier: Modifier = Modifier 的用法

Google 引荐在自界说一个Compose的时分,第一个有默认参数值的类型 要用 modifer ,例如:

Jetpack Compose - 初识Modifier (十一)

有人可能会问为啥要这样引荐呢,由于第一个有默认参数类型的 参数 在实际调用的时分 能够不写 xxx=yyy

便是让调用者方便一点 仅此而已, 接着看上面红框中的代码 ,有人觉得 这个代码好古怪啊

由于我点进去今后 发现这个Modifier是一个目标啊,目标也能够做参数类型了?

Jetpack Compose - 初识Modifier (十一)

仔细看看,其实不然

Jetpack Compose - 初识Modifier (十一)

这个Modifier实质上 他首要是一个接口,在这个接口之中,咱们界说了一个

companion object : Modifier

Modifier的伴生目标,留意这个目标是完成了Modifier接口的,仅仅这个目标名字和interface的名字一样。

这个语法糖在很多当地都有调用,比方kotlin的协程中 就有这个东西,有爱好的能够自己看一下,

所以再看一下这个写法:

Jetpack Compose - 初识Modifier (十一)

第一个参数是接口,默认值是一个名为Modifier的半生目标 他完成了Modifer 这个接口

如何了解Modifier的链式调用

看下面这行代码

Modifier.background(Color.Green)

咱们点进去看今后能够得到下图:

Jetpack Compose - 初识Modifier (十一)

通过这张图,咱们能够得到如下若干个信息

1.backgroun是Mofifer接口的一个扩展函数 2.这个扩展函数实质上 是调用了Modifier这个接口的then办法 3.这个then办法的参数 是Background这目标

咱们首要来看 Modifier这个接口的then 办法是个啥

Jetpack Compose - 初识Modifier (十一)

能够看出来这个then办法实质上便是 A.then(B)

假如这个B是Modifier这个伴生目标 那么就回来A 假如不是 则 把AB 组合起来

留意这个是Modifier这个接口的 then办法完成, 但是回到咱们末节开头的办法调用

Modifier.background(Color.Green)

这儿实质是啥? 是用的Modifier这个伴生目标,所以 这儿要看的是Modifier这个伴生目标的then办法完成

那他的完成便是

Jetpack Compose - 初识Modifier (十一)

那么明显 Modifer.background 这个调用 就等于 Modifier then (Background) 一起他的回来值也是 Background这个目标

这儿一定要搞清楚 不然后面是无法了解Modifer链式调用的

一起咱们也能猜到了 这个Background也一定完成了Modifier这个接口

Jetpack Compose - 初识Modifier (十一)
Jetpack Compose - 初识Modifier (十一)
Jetpack Compose - 初识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 只要三种

  1. CombinedModifier ,他的作用便是能够装载n个Modifier 放到一起
  2. Modifier接口内界说的名为Modifier的伴生目标
  3. 完成了Element这个接口的 Modifier

ComposedModifier

这是一个特别的Modifier,专门用一个末节来了解一下 能够看下这个界说,一个private的class 咱们无法直接调用

Jetpack Compose - 初识Modifier (十一)

看下用法的作用差异:

// 这个写法代表 代码执行到这儿 就立即创立一个padding作用的Modifier
Modifier.padding(10.dp)
// 这个写法代表 传进去了一个lambda表达式,等到真实需求用到的时分才会创立这个padding作用的Modifier
Modifier.composed { Modifier.padding(10.dp) }

有人要问了,真实需求用到的时分才创立是啥意思?,能够近似的了解为layout的时分才创立

能够跟一下代码

Jetpack Compose - 初识Modifier (十一)

Jetpack Compose - 初识Modifier (十一)

Jetpack Compose - 初识Modifier (十一)

Jetpack Compose - 初识Modifier (十一)

Jetpack Compose - 初识Modifier (十一)

代码全体上并不难分析,最终便是落到 materialize 这个函数里边

能够看到里边其实便是一个循环,在循环的时分判断 假如是ComposedModifier 那就创立出来一个真实的Modifier目标

到这儿是不是又懵了,这样做到底有啥特别作用呢? 我直接在Box创立的时分就直接弄一个Modifier出来不行吗

比方说下面这2个写法,实质上 除了创立modifer的机遇不同,其他在展示作用上一摸一样的

Jetpack Compose - 初识Modifier (十一)

能够看一下下面这个比如

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
        }
}