LayoutInflater
LayoutInflater 主要作用是加载以xml 为后缀的布局文件,
基本用法
有两种实现方式,如下:
123LayoutInflater layoutInflater = LayoutInflater.from(context);LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);加载布局文件
官方文档中提供四种方法,我们经常使用其中的两种,如下:
123View inflate (int resource,ViewGroup root)View inflate (int resource,ViewGroup root,boolean attachToRoot)先说一下这几个的参数,
resource是要加载的布局id,root是指给该布局的外部再嵌套一层父布局,如果不需要直接传null,attachToRoot是一个布尔值,为 true 表示返回的 View 是 root,也就是根布局,按照LayoutParams参数设置的 View 将会被加入到 Root 中;为 false 表示返回的是按照父布局的LayoutParams参数设置的 View;总结一下:
- 如果 root 为 null,attachToRoot 没有任何意义。
- 如果 root 不为 null,attachToRoot 为 true,会为加载的布局文件指定一个父布局,即 root。
- 如果 root 不为 null,attackToRoot 为 false,则将布局文件最外层的所有 layout 属性进行设置,当该 view 被添加到父 View 中时,这些 layout 属性会自动失效。完全按照父布局的 params 去设置。
- 如果不设置 attachToRoot 参数的情况下,如果 root 不为 null,attachToRoot 参数默认为 true。
源码解析
inflate 方法的重载最终会走到下面代码中,如下:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103public 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 xmlfinal 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 suppliedparams = 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) {final InflateException ie = new InflateException(e.getMessage(), e);ie.setStackTrace(EMPTY_STACK_TRACE);throw ie;} catch (Exception e) {final InflateException ie = new InflateException(parser.getPositionDescription()+ ": " + e.getMessage(), e);ie.setStackTrace(EMPTY_STACK_TRACE);throw ie;} finally {// Don't retain static reference on context.mConstructorArgs[0] = lastContext;mConstructorArgs[1] = null;Trace.traceEnd(Trace.TRACE_TAG_VIEW);}return result;}}在上述代码中,调用了 createViewFromTag() 方法,它的作用是根据节点名来创建 View 对象 temp。
当 root 不为 null,attachToRoot 为 false 时,为 temp 设置了 LayoutParams。
当 root 不为 null,attachToRoot 为 true 时,将 temp 按照 params 添加到 root 中。
如果 root 为 null 或者 attachToRoot 为 false, 则将 temp 赋值给 result;
总结一下,
Inflate (resId , null ) 只创建 temp ,返回 temp
Inflate (resId , parent, false )创建 temp,然后执行 temp.setLayoutParams(params); 返回temp
Inflate (resId , parent, true ) 创建 temp,然后执行 root.addView(temp, params); 最后返回root
回答一下我们开发中遇到的问题,
Inflate (resId , null ) 不能正确处理宽和高是因为:layout_width,layout_height是相对了父级设置的,必须与父级的LayoutParams一致。而此temp的getLayoutParams为null
Inflate (resId , parent,false ) 可以正确处理,因为 temp.setLayoutParams(params);这个 params 正是root.generateLayoutParams(attrs);得到的。
Inflate (resId , parent,true )不仅能够正确的处理,而且已经把 resId 这个 view 加入到了 parent,并且返回的是 parent,和以上两者返回值有绝对的区别,
Tools 属性
我们可以在xml文件中写下面的话:
|
|
tools 属性用来在xml 文件中,用来在布局和编译时控制布局文件的属性;在运行时相应的属性消失。
GIT
配置全局账户和本地账户
123456789//全局git config --global user.name "name"git config --global user.email "name.com"//本地git config user.name "name"git config user.email "name.com"//取消全局 user.namegit config --global --unset user.namegit config --global --unset user.email解决账户冲突
如果只需要修改最近一次提交,使用
git commit —amend命令1git commit --amend --author="Author <Author.com>"
扫清知识盲点,继续努力。