昨天梳理了一下LayoutInflater解析xml的简单脉络,简单的分析了下xml创建View的过程,在parentView构建子View的过程中在rinflate方法里面发现下面的一段代码:
final View view = createViewFromTag(parent, name, attrs); final ViewGroup viewGroup = (ViewGroup) parent; //创建一个layoutPrarams对象 final ViewGroup.LayoutParams params = viewGroup.generateLayoutParams(attrs); //继续递归调用 解析当前view 的子view rInflate(parser, view, attrs, true); //把生成的view添加到parent view中 //需要注意的是addView每次都调用了该子view的parentView所产生的Layoutparams对象 viewGroup.addView(view, params);上面的这几行代码可以得到如下结论:
1)child View的布局参数LayoutParams是由parent View创建出来,并设置给child View的。
2)观察View的源码可知,该类提供了setLayoutParams方法,所以android中所有的子View都可以调用该方法设置布局参数LayoutParams。
3)需要注意的是View是没有提供generateLayoutParams这个方法,该方法是在ViewGroup里面定义的。所以只有ViewGroup及ViewGroup的子类才可以重写generateLayoutParams方法,从而构建LayoutParams。而View及View的子类只能被动的调用setLayoutParams来设置ViewGroup创建的LayoutParams对象;换句话说LayoutParams不是给parentView使用,而是给parentView的childView使用的。其实这点也很好理解,LayoutParams ,翻译为布局参数。布局,是谁布局?当然是childView在parentView中布局,childView携带了LayoutParams信息高速parentView它想要的大小,正如android API所说 LayoutParams are used by views to tell their parents how they want to be laid out.。
在android中,LayoutParams的类很庞大,他们所有的父类都是ViewGroup的LayoutParams,查看它的api可知有如下关系:
这些子LayoutParams所在的View又都重写了generateLayoutParams方法,所以在解析xml文件创建View对象的时候,通过文章开头的几行代码可以知道每个View都包含了一个ViewGroup。LayoutParams或者上面其中的一个派生类。