一:前言

困惑起源于这段代码

Composable.clickable(点击1).clickable(点击2).size(100.dp).size(200.dp){
...............
}

Composable是随便一个@Composable函数。结果是:点击二会应用,size100dp会应用。

一开始,我试验size的时候,以为是modifier从右往左应用的,但clickable的处理显然违背了这个事实,再放多一个实例

Text("Hi there!", Modifier.padding(10.dp).border(2.dp, Color.Magenta))

这是一个stack overflow的问题,显示结果如下:

他因此疑惑,modifier应该是从右往左应用的吧,先border,再padding,十分合理。

二:先上结论

  • modifier的应用既不是从左往右,也不是从右往左,而是从左往右,然后从右往左回来
  • modifier有很多种类,既有控制触摸的pointer modifier,也有border的draw modifier,也有padding/size这些layout modifier
  • layout modififier和其他modifier的处理都不一样,layout modifier会从左往右传递constraint,又从右往左传递size回来。也就是说,layout modifier是左到右,然后右到左走两遍,其他modifier是从右到左只走一遍
  • constraint是约束的意思,类似于view系统中的MeasureSpec,不过constraint做的更多,可以抽象成拥有四个参数,最小宽,最大宽,最小高,最大高。左边的layout modifier把constraint 传给右边的layout modifier,右边的layout modifier测量之后,把尺寸信息传给左边。
  • layout modifier都有一个measure方法用来测量大小。

三:上示例解释

Box(modifier = Modifier.height(200.dp).width(250.dp)){
Text("Hello, honey?",
Modifier
.fillMaxSize()
.padding(10.dp)
.size(100.dp)
.border(1.dp, Color.Black)
.size(200.dp))
}

最外面的box仅仅起到一个控制范围的作用,不要考虑,我们要做的是分析这个text的modifier。

开始喽!!!

1: 首先,最外面的Box给到第一个modifier 约束,如图所示。

2:fillmaxsize会把约束都撑大,因此它测量下一个modifier给到的约束是min max都为一个固定最大值。

3:padding收到约束,因为它需要四周留空。这里插一个小知识,modifier是针对当前composable自身的,和content无关。因此padding考虑它自身一定要留空那么多padding,所以它会像一个吝啬地主那样,把钱克扣很多之后,才给它下面的员工。因此它把约束都减掉2 * padding。图中画错了,因该是230 和 180.

4: size收到约束,它一看,你TM给我那么多空间吗!!太好了吧!!可是我不需要那么多,我只需要100,我把约束设为100,然后传给下一个。

5:border不是layout modifier不会对约束处理,它是从右往左的时候才会应用的。直接把约束传过去。

6:size200对于上面把约束固定死了的,无能为力,继续传100.

7:  最后,整个text收到100 x 100的信息,它就把自己size设为100 x 100,然后把size信息(蓝色部分)传上去

6:size200不更改这个100 x 100的size信息,继续传上去

5:size信息传到border这里,添加了border信息。

4:传到size100这里,继续把size信息传上去

3:padding加上约束,size变为120 x 120, 这里注意啦,先添加的border信息,再添加的padding信息!!!,这解释了stack over flow那个问题。

2:120 x 120传到fillmaxsize这里,它很霸道啊,利用下面传上来的信息测得最终大小竟然是250 x 200。

1:Box get it!!心领神会!!

备注: 在从左往右的时候,是约束constraint的传递,会跳过非layout modifier。layout modifier可能修改约束,也可能不修改约束。从右往左的时候,在layout modifier之间传递的,是右边的modifier测得的size大小信息,以及如何摆放等信息,遇到非layout modifier,会添加额外信息!!

四: 源码上

主要涉及LayoutNode,过几天补充。

参考资料:

https://www.youtube.com/watch?v=zMKMwh9gZuI&t=1043s&ab_channel=AndroidDevelopers

https://developer.android.com/codelabs/jetpack-compose-layouts#8

星标:https://stackoverflow.com/questions/64206648/jetpack-compose-order-of-modifiers

https://joebirch.co/android/exporing-jetpack-compose-padding-modifier/

Jetpack Compose的Modifier顺序问题的更多相关文章

  1. Jetpack Compose学习(6)——关于Modifier的妙用

    原文: Jetpack Compose学习(6)--关于Modifier的妙用 | Stars-One的杂货小窝 之前学习记录中也是陆陆续续地将常用的Modifier的方法穿插进去了,本期就来详细的讲 ...

  2. Jetpack Compose学习(5)——从登录页美化开始学习布局组件使用

    原文:Jetpack Compose学习(5)--从登录页美化开始学习布局组件使用 | Stars-One的杂货小窝 本篇主要讲解常用的布局,会与原生Android的布局控件进行对比说明,请确保了解A ...

  3. Jetpack Compose学习(9)——Compose中的列表控件(LazyRow和LazyColumn)

    原文:Jetpack Compose学习(9)--Compose中的列表控件(LazyRow和LazyColumn) - Stars-One的杂货小窝 经过前面的学习,大致上已掌握了compose的基 ...

  4. Jetpack Compose What and Why, 6个问题

    Jetpack Compose What and Why, 6个问题 1.这个技术出现的背景, 初衷, 要达到什么样的目标或是要解决什么样的问题. Jetpack Compose是什么? 它是一个声明 ...

  5. Jetpack Compose和View的互操作性

    Jetpack Compose Interoperability Compose风这么大, 对于已有项目使用新技术, 难免会担心兼容性. 对于Compose来说, 至少和View的结合是无缝的. (目 ...

  6. Jetpack Compose 1.0 终于要投入使用了!

    前言 Jetpack Compose 是用于构建原生界面的「新款 Android 工具包」.2021 Google IO 大会上,Google宣布:「Jetpack Compose 1.0 即将面世」 ...

  7. Android全新UI编程 - Jetpack Compose 超详细教程

    1. 简介 Jetpack Compose是在2019Google i/O大会上发布的新的库.Compose库是用响应式编程的方式对View进行构建,可以用更少更直观的代码,更强大的功能,能提高开发速 ...

  8. Jetpack Compose学习(2)——文本(Text)的使用

    原文: Jetpack Compose学习(2)--文本(Text)的使用 | Stars-One的杂货小窝 对于开发来说,文字最为基础的组件,我们先从这两个使用开始吧 本篇涉及到Kotlin和DSL ...

  9. Jetpack Compose学习(3)——图标(Icon) 按钮(Button) 输入框(TextField) 的使用

    原文地址: Jetpack Compose学习(3)--图标(Icon) 按钮(Button) 输入框(TextField) 的使用 | Stars-One的杂货小窝 本篇分别对常用的组件:图标(Ic ...

随机推荐

  1. 群晖ping自动关机

    因为学校宿舍环境的原因,每天早上10点左右宿管可能会来检查内务情况,然后一定会关闭电闸,就导致如果我的nas在10点半时开机的话用的是UPS的电源,直接导致UPS电量耗竭,而我又不可能一直去观察宿舍有 ...

  2. c++基础知识02

    1.前置与后置区别 #include<iostream> using namespace std; int main() { //前置和后置区别 //前置递增或递减 先让变量加减1 然后进 ...

  3. CF1290E Cartesian Tree

    考虑笛卡尔树的意义: 一个点在笛卡尔树中的子树,代表以他为最小/最大值的区间. 所以一个点的子树大小,一定是类似到达序列边界或者被一个比他更大的数隔离. 考虑记录 \(l_i,r_i\) 为第 \(i ...

  4. 洛谷 P5233 - [JSOI2012]爱之项链(Polya 定理+递推)

    洛谷题面传送门 首先很明显题目暗示我们先求出符合条件的戒指数量,再计算出由这些戒指能够构成的项链的个数,因此考虑分别计算它们.首先是计算符合条件的戒指数量,题目中"可以通过旋转重合的戒指视作 ...

  5. 洛谷 P6914 - [ICPC2015 WF]Tours(割边+找性质)

    洛谷题面传送门 神仙题. 深夜写题解感受真好 我们考虑两个简单环 \(C_1,C_2\)​​​,我们假设颜色种类数为 \(k\)​​​,那么我们需要有 \(C_1,C_2\)​​​ 均符合条件,而由于 ...

  6. AWS EKS 添加IAM用户角色

    作者:SRE运维博客 博客地址: https://www.cnsre.cn/ 文章地址:https://www.cnsre.cn/posts/211203931498/ 相关话题:https://ww ...

  7. python(3)跳过第一行(多行)读入数据

    查了下资料,常见两种办法,一是设置行号,再者是利用python自带的itertools工具. 这里推荐一种新的方法,直接使用readline()函数就搞定. 示例: 创建一个文本文件,内容如下: 1 ...

  8. linux中对errno是EINTR的处理

    慢系统调用(slow system call):此术语适用于那些可能永远阻塞的系统调用.永远阻塞的系统调用是指调用有可能永远无法返回,多数网络支持函数都属于这一类.如:若没有客户连接到服务器上,那么服 ...

  9. Linux三剑客之老三grep

    说明: Linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来.工作中我们常常用它来过滤出我们想要的数据. 格式: grep [OPTIONS] 基本参 ...

  10. Shell 分发脚本

    目录 Shell分发脚本 原理 rsync命令分析 特点 基本语法 实现 需求 环境变量 脚本实现 知识点 获得当前路径的目录dirname 获得当前路径的文件名basename shell远程执行命 ...