Jetpack Compose的Modifier顺序问题
一:前言
困惑起源于这段代码
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顺序问题相关推荐
- JetPack Compose之Modifier修饰符
前言 在Compose中,每一个组件都是带有@Compose注解的函数,被称为Composable.Compose已经预置了很多的Compose UI组件,这些组件都是基于Material Desig ...
- Jetpack Compose中的Modifier
Modifier的基本使用 Modifier修饰符是Jetpack Compose中用来修饰组件的,提供常用的属性,写布局时几乎所有Composable组件的大部分属性都可以用Modifier 来修饰 ...
- 详解Jetpack Compose中的Modifier修饰符
前言 本文将会介绍Jetpack Compose中的Modifier.在谷歌官方文档中它的描述是这么一句话:Modifier元素是一个有序.不可变的集合,它可以往Jetpack Compose UI元 ...
- Jetpack Compose中的手势操作
点击事件 监听点击事件非常简单,使用 clickable 和 combinedClickable 修饰符即可满足需求: @OptIn(ExperimentalFoundationApi::class) ...
- 深入理解 Jetpack Compose 内核:SlotTable 系统
引言 Compose 的绘制有三个阶段,组合 > 布局 > 绘制.后两个过程与传统视图的渲染过程相近,唯独组合是 Compose 所特有的.Compose 通过组合生成渲染树,这是 Com ...
- Jetpack Compose 从入门到入门(三)
本篇开始介绍Jetpack Compose 中的修饰符Modifier.修饰符可以用来执行以下操作: 更改可组合项的大小.布局.行为和外观. 添加信息,如无障碍标签. 处理用户输入. 添加高级互动,如 ...
- Jetpack Compose - Box
Jetpack Compose - Box 0.介绍 1.属性一览 2.使用示例 3.版本更新 4.未解决问题 Compose系列文章,请点原文阅读.原文,是时候学习Compose了! 0.介绍 针对 ...
- Jetpack Compose 深入探索系列四: Compose UI
通过 Compose runtime 集成 UI Compose UI 是一个 Kotlin 多平台框架.它提供了通过可组合函数发出 UI 的构建块和机制.除此之外,这个库还包括 Android 和 ...
- Jetpack compose 康奈尔笔记
快速上手 条目 内容 是什么 原生Android界面构建工具包 优势 -更少的代码 -直观(状态变化,自动更新界面) -可以预览 -Material design 什么是可组合函数 -用函数描述外观和 ...
- Jetpack Compose入门
简介 Jetpack Compose是用于构建原生Android界面的新工具包.它是一种声明式的UI布局,其官方声称可简化并加快Android上的界面开发,使用更少的代码.强大的工具和直观的Kotli ...
最新文章
- 还在重复造轮子?Java开发人员必知必会的20种常用类库和API
- 【题意+解析】1041 Be Unique (20 分)_18行代码AC
- 安装python3.6报错_CentOS 7下安装Python3.6 及遇到的问题小结
- Windows驱动——利用WinDriver开发PCI设备驱动程序
- 如何在spring框架中解决多数据源的问题[转]
- mac如何清空Recent Places
- 《编码的奥秘》记录(二)
- matlab 导出asc文件,将* .asc文件保存为Excel文件
- 选型宝访谈:如何用好移动报销云平台,解放全员工作效率?
- 深度可分离卷积解析 - MobileNetV1
- 华为云IoT提出万物互联新范式,从万物感知到万物生长
- 趣味编程入门 Scratch 开发跳一跳小游戏-邵立志-专题视频课程
- SPSS中的数据分析—信度效度检验【2】
- courant数_CFD中常用的参数介绍 | 坐倚北风
- MYSQL基础(sql语句)
- C语言的函数是什么?
- MySQL基础语法大全(尚硅谷)
- JNLP 文件无法打开的解决办法
- FreeRTOSlwIP
- Facebook Instant Game 捆绑包配置方法