View inflate 原理
由于经常会使用
View view = inflater.inflate(R.layout.fragment_main, container, false); 或者
View view = inflater.inflate(R.layout.dialog_kp_user_product_item, null);
两个方法,但是不知道其有什么区别?如果搞错了会报
Caused by: java.lang.IllegalStateException:The specified child already has a parent. You must call removeView() on the child's parent first.
比如说我们在adapter ,把第三个参数改为true, 在动态添加布局的时候把 null 改为容器view,这样就会出现上面的错误?原因是传了true,表示立即把view 添加到viewGroup中,后面adapter 会再次把view 添加到viewGroup,这时候就会报错说 illegalStateException, 因为view已经被添加了,不能再次被添加。同理,对于
View view = inflater.inflate(R.layout.dialog_kp_user_product_item, null);
也是如此,该方法一般再动态添加布局的时候用到,比如在动态添加布局时候,我们会用到此方法
public void setLayout(View view){View subLayout = LayoutInflater.from(this).inflate(R.layout.sub_layout, null);mLinearLayout.addView(subLayout);}
这里第二个参数传了null,源码追寻,
public void addView(View child, int index) {if (child == null) {throw new IllegalArgumentException("Cannot add a null child view to a ViewGroup");}LayoutParams params = child.getLayoutParams();if (params == null) {params = generateDefaultLayoutParams();if (params == null) {throw new IllegalArgumentException("generateDefaultLayoutParams() cannot return null");}}addView(child, index, params);}public void addView(View child, int index, LayoutParams params) {if (DBG) {System.out.println(this + " addView");}if (child == null) {throw new IllegalArgumentException("Cannot add a null child view to a ViewGroup");}// addViewInner() will call child.requestLayout() when setting the new LayoutParams// therefore, we call requestLayout() on ourselves before, so that the child's request// will be blocked at our levelrequestLayout();invalidate(true);addViewInner(child, index, params, false);}
点击addView,往下走,会看到 addView (View child, int index, LayoutParams params),添加之前会测量一遍,在刷新,最后add,我们点进去addViewInner ,
private void addViewInner(View child, int index, LayoutParams params,boolean preventRequestLayout) {if (mTransition != null) {// Don't prevent other add transitions from completing, but cancel remove// transitions to let them complete the process before we add to the containermTransition.cancel(LayoutTransition.DISAPPEARING);}if (child.getParent() != null) {throw new IllegalStateException("The specified child already has a parent. " +"You must call removeView() on the child's parent first.");}if (mTransition != null) {mTransition.addChild(this, child);}if (!checkLayoutParams(params)) {params = generateLayoutParams(params);}......... 省略后面代码
重点来了,if (child.getParant () != null) 时候抛出一个异常,而内容就是我们刚刚报的异常;这样我们就明白了。inflater.inflate(R.layout.fragment_main, container, false)
打包 inflate 布局的时候不能立即给view添加父布局,否则会抛出异常。注意,这里的表述不能立即给view添加父布局,不是不添加,第三个参数 false 表示 延后添加,true 表示立即添加;同理,inflater.inflate(R.layout.dialog_kp_user_product_item, null);
第二个参数为空自然没有父view ,也就不存在添加一说,当调用root.addView(subLayout)时候,root 会直接添加的,所以这里就不应该再传一个容器view,否则会重复添加,在调用addView的时候就会出错。
总结:一般,添加view的职责是系统做的,当我们调用addView的时候,这个添加任务系统就会帮我们做掉。我们仅仅是需要提供一个view 布局,通过inflate 实现,但是inflater 也能够帮忙添加布局,所以在inflater 就不需要添加布局了。
个人愚见,如有不正,欢迎指出。
参考:https://stackoverflow.com/questions/12567578/what-does-the-layoutinflater-attachtoroot-parameter-mean/45809756#45809756
View inflate 原理相关推荐
- Android刷新机制-View绘制原理
Android刷新机制-View绘制原理 Android刷新机制-SurfaceFlinger原理 Android刷新机制-Choreographer原理 一.概述 本文将从startActivity ...
- Xml转换成view的原理
在开发过程中,我们通常都有在用View.inflate(context, resource, root)方法来创建视图,这个方法非常方便,但是它有个缺点就是没有加载xml 里面设置的布局参数.举个例子 ...
- View.inflate和LayoutInflater的inflate方法区别
平时ListView加载item中,adapter的getView方法中,我们经常用到: LayoutInflater.from(mContext).inflate(R.layout.it ,pare ...
- Android View绘制原理解析
概述 本篇文章主要讲述View是如何在Android源码中产生的,以便于我们能够更好的去自定义一些控件,大体上是按照View绘制的流程来走步骤,在追踪源码之前我们先了解几个基础知识.来看下面的这张图: ...
- View绘制原理 —— 画在哪?
这是Android视图绘制系列文章的第二篇,系列文章目录如下: View绘制原理--画多大? View绘制原理--画在哪? View绘制原理--怎么画? 如果想直接看结论可以移步到第三篇末尾. Vie ...
- View工作原理(一)事件传递原理详解
版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 转载请说明出处:http://blog.csdn.net/ff20081528/article/details/17353869 ...
- Android --- View.inflate()的详细介绍
误用 LayoutInflater 的 inflate() 方法已经不是什么稀罕事儿了-- 做 Android 开发做久了,一定会或多或少地对布局的渲染有一些懵逼: 1.View.inflate() ...
- ndroid中View.inflate()
Inflate可用于将一个xml中定义的布局控件找出来. 因为在一个Activity里如果直接用findViewById()的话,对应的是setConentView()的那个layout里的组件.因此 ...
- android:打气筒功能View.inflate
显示效果如图 1.MainActivity package com.example.listview;import java.util.List; import java.util.Map;impor ...
- 源码分析初级《篇一》 为何建议使用LayoutInflater.from而不用View.inflate
转载文章请注明出处:道龙的博客 我们不管是在ListView.RecyclerView.甚至自定义布局的时候,都会通过View.inflate(......);方法加载布局,其实这是偷懒的方式,有些时 ...
最新文章
- [转]程序员生涯总结
- 一个MySQL存储过程的模板
- Linux下fork()函数
- 原生javascript实现完整的轮播图
- 【干货】十分钟读懂浏览器渲染流程
- numpy数组按某一维度相加_Python数据分析之NumPy(高级篇)
- Python基础(三)--序列
- excel切片器_如何在Excel表格中使用切片器
- Centos 6安装完美搭建mysql、php、apache之旅
- 遍历界面控件 android,Android 判断所有字段是否已经输入的实例
- ssas如何创建分区_如何基于SSAS信息创建Excel报告
- CocoaPods Mac App的安装和使用
- 09-排序2 Insert or Merge
- LINUX下载编译lame
- 注册Flash8.ocx控件
- 光盘中的vob格式怎么转换成mp4格式
- 写一篇基于SPEA2算法的高维多目标救灾物资分配的论文
- iOS中定位以及地图的使用
- html5会员管理,如何搭建会员管理体系?
- 计算机教资科目三书籍,【教资笔试科目三】数学学科复习指导
热门文章
- 神器vimium:比同级程序员成长更快,我主要靠它
- python微博情感分析,Python情感分析:鹿晗的粉丝们究竟原谅他了吗?
- php读取加密表格,Excel表格如何加密
- 郑捷《机器学习算法原理与编程实践》学习笔记(第二章 中文文本分类(三)—KNN算法)...
- 一元二次方程的解c语言,一元二次方程求解程序完整代码
- 怎样从任务管理器打开计算机,怎么打开任务管理器|任务管理器在哪里打开
- Craw the picture of the specific handle
- 为知笔记docker搭建
- WordPress页面教程【2021】
- TIA protal与SCL从入门到精通(3)——软件单元基本介绍