一:前言

困惑起源于这段代码

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

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

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

  1. 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方法用来测量大小。

三:上示例解释

  1. Box(modifier = Modifier.height(200.dp).width(250.dp)){
  2. Text("Hello, honey?",
  3. Modifier
  4. .fillMaxSize()
  5. .padding(10.dp)
  6. .size(100.dp)
  7. .border(1.dp, Color.Black)
  8. .size(200.dp))
  9. }

最外面的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. [luogu7207]Sob

    为了方便,先将$n$减小1,即两者范围分别为$[0,n]$和$[m,m+n]$ 结论:取$u=\min_{i\in [m,m+n],n\& i=n}i$,则$\forall 0\le i\le ...

  2. [hdu6580]Milk

    考虑定义以下dp数组:1.g1[i][j]表示第i行从中间出发向左取j瓶牛奶最少要多久2.g2[i][j]表示第i行从中间出发向右取j瓶牛奶最少要多久3.g3[i][j]表示在g1[i][j]的基础上 ...

  3. [loj3276]遗迹

    假设已知$a_{i}$,通过以下方式确定$b_{i}$:从后往前枚举每一个数$i$,先令$b_{i}=a_{i}$,再将$b_{i}$不断减1直至不存在$j>i$且$b_{i}=b_{j}$或$ ...

  4. WinRAR下载

    https://www.win-rar.com 垃圾7Z有的解压不了.

  5. Insights直播回顾,对话专家,HMS Core 6创新能力解读

    HMS Core Insights第八期直播–对话专家,HMS Core 6创新能力解读,已于11月25日圆满结束,本期直播与小伙伴们一同了解了HMS Core 6在图形.媒体以及连接与通信领域推出的 ...

  6. Linux查看进程

    1.ps 有很多参数,不需要全部记住,只需要记住最有用的那些参数. unix风格的参数 比如:ps -ef查看系统上运行的所有进程 ps -l 会产生一个长格式的输出   >UID:启动这些进程 ...

  7. python11文件读写模块

    将文件的打开和关闭,交给上下文管理工具with去实现. def read_file(): """ 读取文件 :return: """ fil ...

  8. mysql 实现某年单季度内的品牌TOPn销量在此年此单季度内销量占比

    数据表:       结果表: mysql语句:  

  9. (转载)Java生成和操作Excel文件

    JAVA EXCEL API:是一开放源码项目,通过它Java开发人员可以读取Excel文件的内容.创建新的Excel文件.更新已经存在的Excel文件.使用该API非Windows操作系统也可以通过 ...

  10. 数据库之JDBC

    1.简单认识一下JDBC 1).JDBC是什么? java database connection       java数据库连接 作用:就是为了java连接mysql数据库嘛 要详细的,就面向百度编 ...