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学习(6)——关于Modifier的妙用
原文: Jetpack Compose学习(6)--关于Modifier的妙用 | Stars-One的杂货小窝 之前学习记录中也是陆陆续续地将常用的Modifier的方法穿插进去了,本期就来详细的讲 ...
- Jetpack Compose学习(5)——从登录页美化开始学习布局组件使用
原文:Jetpack Compose学习(5)--从登录页美化开始学习布局组件使用 | Stars-One的杂货小窝 本篇主要讲解常用的布局,会与原生Android的布局控件进行对比说明,请确保了解A ...
- Jetpack Compose学习(9)——Compose中的列表控件(LazyRow和LazyColumn)
原文:Jetpack Compose学习(9)--Compose中的列表控件(LazyRow和LazyColumn) - Stars-One的杂货小窝 经过前面的学习,大致上已掌握了compose的基 ...
- Jetpack Compose What and Why, 6个问题
Jetpack Compose What and Why, 6个问题 1.这个技术出现的背景, 初衷, 要达到什么样的目标或是要解决什么样的问题. Jetpack Compose是什么? 它是一个声明 ...
- Jetpack Compose和View的互操作性
Jetpack Compose Interoperability Compose风这么大, 对于已有项目使用新技术, 难免会担心兼容性. 对于Compose来说, 至少和View的结合是无缝的. (目 ...
- Jetpack Compose 1.0 终于要投入使用了!
前言 Jetpack Compose 是用于构建原生界面的「新款 Android 工具包」.2021 Google IO 大会上,Google宣布:「Jetpack Compose 1.0 即将面世」 ...
- Android全新UI编程 - Jetpack Compose 超详细教程
1. 简介 Jetpack Compose是在2019Google i/O大会上发布的新的库.Compose库是用响应式编程的方式对View进行构建,可以用更少更直观的代码,更强大的功能,能提高开发速 ...
- Jetpack Compose学习(2)——文本(Text)的使用
原文: Jetpack Compose学习(2)--文本(Text)的使用 | Stars-One的杂货小窝 对于开发来说,文字最为基础的组件,我们先从这两个使用开始吧 本篇涉及到Kotlin和DSL ...
- Jetpack Compose学习(3)——图标(Icon) 按钮(Button) 输入框(TextField) 的使用
原文地址: Jetpack Compose学习(3)--图标(Icon) 按钮(Button) 输入框(TextField) 的使用 | Stars-One的杂货小窝 本篇分别对常用的组件:图标(Ic ...
随机推荐
- [atAGC045C]Range Set
首先我们可以把所有位置都变为1,因此不妨假设$a\le b$ 一个字符串$s$合法当且仅当:将其中每一段长度不小于$a$的0变成1后,存在一段1的长度都不小于$b$ 证明:我们称$S_{a,b}$为通 ...
- Electron快速入门之事件
const { app, BrowserWindow } = require('electron') function createWindow () { const win = new Brow ...
- tomcat的log日志乱码解决方案
Intellij idea Tomcat输出log中文乱码 配置tomcat在VM options添加-Dfile.encoding=UTF8 -Dsun.jnu.encoding=UTF8 重启后控 ...
- JdbcTemplate 、Mybatis、ORM 、Druid 、HikariCP 、Hibernate是什么?它们有什么关系?
JdbcTemplate .Mybatis.ORM .Druid .HikariCP .Hibernate是什么?它们有什么关系? 学完Spring和SpringMVC之后,就急于求成的开始学习起Sp ...
- ARC128D
考虑我们直接\(dp\). 那么需要快速的求出一段是否可以被消掉只剩两端. 我们可以考虑反过来做的. 我们知道如果全为\(abab\)型或者\(aa\)型则无法消掉 那么我们要前缀和,以及遇到\(aa ...
- Atcoder 2444 - JOIOI 王国(二分)
题面传送门 记 \(mxi\) 为 IOI 国海拔的最大值,\(mni\) 为 IOI 国海拔的最小值,\(mxj\) 为 JOI 国海拔的最大值,\(mnj\) 为 JOI 国海拔的最小值. 不难发 ...
- Matlab指针数组
Matlab指针数组 前面博客Matlab指针中介绍了如何在Matlab中使用handle类型对象作为指针使用,本文则介绍一些使用这些类型指针的小技巧. 自定义类型的指针数组 在大部分编程语言中,我们 ...
- FVCOM编译过程详解
本文目的旨在介绍fvcom编译的全过程,顺便介绍linux中make命令的文件写法和一般的编程过程简述一下. 1.编程过程 编程,一般就是编写可执行程序过程.这个过程主要是源文件生成中间代码文件,再到 ...
- nginx 文件目录页面
开启文件目录 server { listen 80; #设置自己静态目录的访问域名 server_name xxx.xxxx.com; #防止页面中文乱码一定要在utf-8前面加上gbk,顺序很重要 ...
- Linux运维工程师面试题整理
1. Nginx 反向代理,负载均衡,动静分离,工作原理及优化nginx配置反向代理. vim Nginx.confServer模块中配置Listen 80Server_name ip;在server ...