inflater(...)源码解析
来源:互联网 发布:学python往哪方面就业 编辑:程序博客网 时间:2024/05/16 06:29
以ListView来演示,下面为三种为item的View填充的方法
- view = LayoutInflater.from(MainActivity.this).inflate(R.layout.item, null);
- view = LayoutInflater.from(MainActivity.this).inflate(R.layout.item, new LinearLayout(MainActivity.this), true);
- view = LayoutInflater.from(MainActivity.this).inflate(R.layout.item, new LinearLayout(MainActivity.this), false);
item的布局文件
<Button xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="120dp" android:layout_height="120dp" android:orientation="vertical" android:text="这里"></Button>
效果图
- 第一种:布局文件最外层设置无效
- 第二种:root不为空attachToRoot为true,布局文件最外层设置有效
第三种:root不为空attachToRoot为false,布局文件最外层设置有效
源码分析
public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) { synchronized (mConstructorArgs) { Trace.traceBegin(Trace.TRACE_TAG_VIEW, "inflate"); final Context inflaterContext = mContext; final AttributeSet attrs = Xml.asAttributeSet(parser); Context lastContext = (Context) mConstructorArgs[0]; mConstructorArgs[0] = inflaterContext; View result = root; try { // Look for the root node. int type; while ((type = parser.next()) != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT) { // Empty } if (type != XmlPullParser.START_TAG) { throw new InflateException(parser.getPositionDescription() + ": No start tag found!"); } final String name = parser.getName(); if (DEBUG) { System.out.println("**************************"); System.out.println("Creating root view: " + name); System.out.println("**************************"); } if (TAG_MERGE.equals(name)) { if (root == null || !attachToRoot) { throw new InflateException("<merge /> can be used only with a valid " + "ViewGroup root and attachToRoot=true"); } rInflate(parser, root, inflaterContext, attrs, false); } else { // Temp is the root view that was found in the xml final View temp = createViewFromTag(root, name, inflaterContext, attrs); ViewGroup.LayoutParams params = null; if (root != null) { if (DEBUG) { System.out.println("Creating params from root: " + root); } // Create layout params that match root, if supplied params = root.generateLayoutParams(attrs); if (!attachToRoot) { // Set the layout params for temp if we are not // attaching. (If we are, we use addView, below) temp.setLayoutParams(params); } } if (DEBUG) { System.out.println("-----> start inflating children"); } // Inflate all children under temp against its context. rInflateChildren(parser, temp, attrs, true); if (DEBUG) { System.out.println("-----> done inflating children"); } // We are supposed to attach all the views we found (int temp) // to root. Do that now. if (root != null && attachToRoot) { root.addView(temp, params); } // Decide whether to return the root that was passed in or the // top view found in xml. if (root == null || !attachToRoot) { result = temp; } } } catch (XmlPullParserException e) { InflateException ex = new InflateException(e.getMessage()); ex.initCause(e); throw ex; } catch (Exception e) { InflateException ex = new InflateException( parser.getPositionDescription() + ": " + e.getMessage()); ex.initCause(e); throw ex; } finally { // Don't retain static reference on context. mConstructorArgs[0] = lastContext; mConstructorArgs[1] = null; } Trace.traceEnd(Trace.TRACE_TAG_VIEW); return result; } }
- 三种情况最终都会来到以上代码块进行最后的处理
参数分析
- parser:item的布局文件经过XmlPullParaer之后的
- root:inflater中传入的父布局文件
- attachToRoot:inflater中传入的boolean类型
关键代码
- 第9行:初始化result,携带root引用,该属性为最终返回值
- 第42行:获取item中的最顶层的view,初始化temp并获得引用
- 第46~58行:若root不为空,则获取temp中的attrs,之后再次判断是否attach to root,若为false,则在此temp.setLayoutParams(attrs),若为true,看注释
- 第65行:将item中的子view填充进temp中
- 第73~75行:在root不为空,并且attachToRoot为True的情况下,将temp和attrs添加到root中
- 第79~81行:在root为空或者attachToRoot为false的情况下,result=temp并且最终返回
分析
- 第一种:因为root为空,而attachToRoot为false,所以丢失了item中顶层的attrs属性
- 第二种:root不为空,attachToRoot为true,通过root.addView(temp,attrs),所以attrs属性没丢失
- 第三种:root不为空,attachToRoot为false,通过temp.setLayoutParams(attrs),所以attrs属性没丢失
注意点
- temp.setLayoutParams(attrs):该方法为设置该View在父类中的位置属性,例如layout_width
1 0
- inflater(...)源码解析
- android inflater详解以及源码解析
- Inflater
- Inflater
- inflater
- inflater
- Inflater
- inflater
- Inflater
- LayoutInflater.inflater()方法及参数源码分析
- android inflater
- inflater用法
- android inflater
- inflater参数
- android Inflater
- inflater用法
- 源码解析
- 源码解析
- 文本框只能输入数字
- python程序部署在Windows系统
- Unity对象池技术
- Scr888 Casino Refer Poker Card Giveaway in iBET
- cmd 关闭系统进程
- inflater(...)源码解析
- Android程序员学PHP开发(33)-ThinkPHP5.0(5)命名空间与TP5-PhpStorm
- 开源硬件3.0时代降临
- Android响应式编程开发RxAndroid(5):RxJava 2.0的Consumer
- 单例模式及其资源释放
- afxDump怎么用
- Oracle体系结构和启动关闭阶段
- [机器学习篇]基于Scikit learn库中KNN,SVM算法的笔迹识别
- linode上快速建立Spark源码阅读环境