IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android吃透inflate方法(一) -> 正文阅读

[移动开发]Android吃透inflate方法(一)

从inflate方法开始,搞懂LayoutInflater的inflate过程

在Android开发过程中,很多地方都不可避免的使用到inflate方法,如在使用RecycleView的时候构建ViewHolder对象,给Fragment进行CreateView

我们通常是inflater.inflate(R.layout.xxx, container, false)或者LayoutInflater.from(parent.context).inflate(R.layout.xxx, parent, false)来调用inflate方法的,不难发现,inflate方法的作用是将一个?xml?布局文件变成一个?view?对象。

那么,我们就来将它「分解」成明确的「问题」,来具体的「学习」吧

  1. LayoutInflaterinflater?这些语句的「头部」是什么?怎么来的?
  2. inflate?方法的「参数」是什么意思,有什么用?
  3. 这些语句是怎么实现转换?xml?为?view?的?
  4. 我除了常见的用法还能怎么用它

问题一:

? ? 思考的First Step,问其所来

  1. 这玩意是用来将?xml?转换为?view?的
  2. 这玩意不能直接new初始化,通过ActivitySystemService获取,你也可以自定义他的工厂方法
  3. 因为性能问题,他只能把写在layout里被预处理过的?xml?转换为?view?,不能随便找个xml文件就让他转换

总结:

那好了,第一个问题解决了,LayoutInflater是一个不能直接new的类,他来管?xml?转换为?view?,我们在adapter里通过LayoutInflater.from(context)获取实例,fragment则是直接使用了FragmentManager调用Fragment.onCreateView的时候传过来的inflater对象

问题二:

inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot)?方法有三个参数,第一个参数很好理解,就是前文所说的,?xml?转换为?view?中?layout xml?对应的资源ID。第二第三个参数又什么意思呢?我转换成View为什么需要它呢?

  1. root是要转换的?xml?将要存在的外部ViewGroup
  2. xml?转换成?view?后要不要?addView?到?root?(?ViewGroup?)

是不是看不懂,我们接着看!!!

这里提一下:View和ViewGroup的关系----简单来说就是玻璃和玻璃框的关系

测试

纸上学来终觉浅,只是看文档还是不行,不如自己上手试试,把自己脑子里的可能性都弄出来试试看效果,跑出来啥样就是啥样了。

按排列组合来说,我们一共有四种(如果你想到更多可能性,不妨自己写出来跑跑看)

  1. root = null, attachToRoot = false
  2. root = null, attachToRoot = true
  3. root = viewgroup, attachToRoot = false
  4. root = viewgroup, attachToRoot = true

接下来我们一个个实验,实验的过程为,通过activitygetLayoutInflater()方法获取inflater对象,调用其inflate方法,传递不同的参数,将得到的view添加到activity布局的viewgroup中,查看结果。

首先是布局展示,activity的布局只有一个蓝底的ViewGroup,而要加载的view也只是一个黄色的View

?

注意我给蓝底加了一句android:paddingTop="32dp",黄底加了一句android:layout_margin="4dp"

测试①

我们看到黄色的view几乎填满了整个activityviewwidthheightmargin都无效,但是viewgrouppadding是有效的。

但是我们还不能确定是root = nullattachToRoot = false中哪个的原因,我们继续测试

测试②

我们可以看到黄色的view里面设置的width?height?margin还是无效的,但是viewgrouppadding是有效的。

通过这两个测试,我猜测root的效果是控制?xml?里关于layoutparam的设置是否有效,但是不是这样还要看接下来的测试。而viewgroup的padding参数是不受影响的,这个也好理解,因为是ViewGroup的属性,在onDraw方法里处理的。

测试③

?

我们可以看到黄色的view里面设置的width?height?margin也都有效了

也就是说,root的猜测基本是坐实了,接下来就剩attachToRoot还是一头雾水了

测试④

Crash!出问题了,看看报错信息:

The specified child already has a parent. You must call removeView() on the child's parent first.

这娃儿已经有个爹了,你要当他爹得先让他现在的爹 removeView()

啥意思,已经有个爹了?这爹是谁,他转换的过程也就接触到一个viewgroup啊,难道说attachToRoot = true的话就直接addView()了?试试看

测试⑤

?

果然和我们想的一样……那么,可以总结一下了

总结

  1. root参数将决定viewlayoutparam,如果为null,那xml里定义的最外层viewlayoutparam将全部无效
  2. attachToRoot表示是否需要一键addView(),如果root为null,那这个参数将被自动忽略(表示是否将第一个参数所指定的布局添加到第二个参数的View中。)

第一点失效的详解:

我们在开发的过程中给控件所指定的layout_width和layout_height到底是什么意思?该属性的表示一个控件在容器中的大小,就是说这个控件必须在容器中,这个属性才有意义,否则无意义。

这就意味着如果我直接将linearlayout加载进来而不给它指定一个父布局,则inflate布局的根节点的layout_width和layout_height属性将会失效(因为这个时候linearlayout将不处于任何容器中,那么它的根节点的宽高自然会失效)

如果我想让linearlayout的根节点有效,又不想让其处于某一个容器中,那我就可以设置root不为null,而attachToRoot为false。这样,指定root的目的也就很明确了,即root会协助linearlayout的根节点生成布局参数,只有这一个作用。

原因:

那为什么Activity布局的根节点的宽高属性会生效?其实原因很简单,大部分情况下我们一个Activity页面由两部分组成(Android的版本号和应用主题会影响到Activity页面组成,这里以常见页面为例),我们的页面中有一个顶级View叫做DecorView,DecorView中包含一个竖直方向的LinearLayout,LinearLayout由两部分组成,第一部分是标题栏,第二部分是内容栏,内容栏是一个FrameLayout,我们在Activity中调用setContentView就是将View添加到这个FrameLayout中,所以给大家一种错觉仿佛Activity的根布局很特殊,其实不然。

?

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-10-06 12:20:40  更:2021-10-06 12:22:35 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 9:58:49-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码