我们都知道,使用RecyclerView时,需要填充一个item.xml。但是我运行程序员后,发现item.xml的根View的layout属性没有生效,解决办法就是将inflate(R.layout.item,null)改成inflate(R.layout.item,parent,false)。决解问题后并不满足,想看一看源码了解产生这个坑的原因。
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new Viewholder(inflater.inflate(R.layout.item,null));
}
R.layout.item代码
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:orientation="vertical"
android:padding="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textColor="#ffff"
android:text="aaaaaaaaaaaaa"/>
LinearLayout>
LinearLayout的layout属性失效。
为什么将inflate(R.layout.item,null)改成inflate(R.layout.item,parent,false)就好了呢?这里最关键的时前者root参数是空。后者是parent,不为空。我们看源码比较一下这两个的差别。
三个参数的inflate
public View inflate (int resource, ViewGroup root, boolean attachToRoot)
两个参数的inflate
public View inflate (int resource, ViewGroup root)
作用:将xml布局文件实例化为它对应的View对象
两个参数和三个参数的源码一样,两个参数的会转化成三个参数的。
public View inflate(XmlPullParser parser, @Nullable ViewGroup root) {
return inflate(parser, root, root != null);
}
源码(这里只截取关键部分):
public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) {
final AttributeSet attrs = Xml.asAttributeSet(parser);
final String name = parser.getName();//获取根view的名字
final View temp = createViewFromTag(root, name, inflaterContext, attrs);//temp是xml的根view,也就是最外层的ViewGroup。我们所说的layout属性失效,也是指这个view。
if (root != null) { //这两个的差别主要在这里
params = root.generateLayoutParams(attrs);//生成LayoutParams
if (!attachToRoot) {
temp.setLayoutParams(params);//设置LayoutParams
}
}
rInflateChildren(parser, temp, attrs, true);//实例化temp的所有子view
if (root == null || !attachToRoot) {
result = temp;
}
return result;//返回实例化后的view
}
看到这里大家应该明白了,不获取LayoutParams,Layout属性当然就没用了。