解决方案:
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// View view = View.inflate(parent.getContext(), R.layout.item_fra_main2, null);
View view = mInflater.from(mContext).inflate(R.layout.item_fra_main2, parent, false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
原理说明:
View.inflate(parent.getContext(), R.layout.item_fra_main2, parent);
对应的是:LayoutInflate.inflate(resource , parent, true);//在RecycleView下奔溃
View.inflate(parent.getContext(), R.layout.item_fra_main2, null);
对应的是:LayoutInflate.inflate(resource , null, false);//match_parent属性失效
mInflater.from(mContext).inflate(R.layout.item_fra_main2, parent, false);
对应的是:LayoutInflate.inflate(resource , parent, false);//就需要这种方案
分析一:
分析二、
现在就看为什么代码二中的match_parent失效问题了,以及代码三的match_parent有效的情况。
先说代码三,分析原因肯定是跟源码了
从源码中可以看出,传入 parent 参数,null与非null的分水岭就在于,对childView是否需要setLayoutParams。
来看看setLayoutParams 里面都做了什么?
这里有一段非常的重要,就是childview会去通知parentVIew也去调用这个函数。因此直到最底部的RootView都会被通知调用这个函数。
分析三、
现在知道分水岭之后。就要看看RecycleView是怎么加载ChildView的了。
直接调出RecyclerView.java类,RecycleView中有个mChildHelper变量。
找到了加载ChildView的入口。继续跟踪到AddView里面(ViewGroup.java)
哈哈!这边又有一个分水岭,从Inflate中的分水岭关于Params的问题,这边就呈现出来了。
如果,Inflate中设置了Parent,那么RecycleView就会使用ChildView配置的params去add ChildView。因此,这时候的match_parent就会生效。
分析四、
那为什么params为null后,addView()函数导致了childview中的match_parent实效呢?导致实际的效果与预想不同,而只是自适应大小。
再研究下addView的源码:
里面有句话child.getLayoutParams(),而getLayoutParams方法说明中有句话为:This method may return null if this View is not attached to a parent ViewGroup。意思就是如果没有被添加至父控件时,结果是会返回null的,很显然,到目前的代码跟踪情况来看,vChild还没有被添加至linParent,所以会去调用generateDefaultLayoutParams()方法,而generateDefaultLayoutParams的方法实现如下:
protected LayoutParams generateDefaultLayoutParams() { return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); }
所以就很明显的造成了子布局android:layout_width="match_parent"属性失效。