背景

今天在写一个item布局时设置的宽度为match-parent,可是显示出来的内容却是和我想象中的布局样式不一样,明明应该是占满屏幕的,怎么就自适应了呢?为什么就成了wrap-content的效果呢?后来我就上网查了了一下,设置的match-parent失效的原因,这一搜还真让我搜出了点东西。

我们常用的便是LayoutInflater的inflate方法,这个方法有四个重载方式,分别是

  • public View inflate(int resource, ViewGroup root)
  1. public View inflate(int resource, ViewGroup root, boolean attachToRoot)
  2. public View inflate(XmlPullParser parser, ViewGroup root)
  • public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot)

我们用的最多的便是在RecyclerView的Adapter中

类似于这样

1
2
3
4
5
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
{ return new Holder(mContext,mlayoutInflater.inflate(R.layout.xxxx,null);
}

我在网上搜到的Adapter代码是这样的,于是我机智的改了我的代码

1
2
3
4
5
6
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull
ViewGroup parent, int viewType)
{ return new
Holder(mContext,mlayoutInflater.inflate(R.layout.xxx, parent, false));}

运行了一遍之后发现可以了!!!竟然可以了。。。。

我就想为什么呢?我查到的资料是这样的

源码很长主要关注这一段就好了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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);
}
}

就是当root不是空的时候,并且attachToRoot是false时,就把root的参数设置给temp,那root的实参parent是什么呢?

在这个函数中,parent的实参就是RecyclerView,就是item的父布局,我们创建的布局设置的layout参数都要依赖于这个父视图,没有这个父视图(null)就等于告诉框架不需要父视图去添加你的view

1
2
3
4
5
// Decide whether to return the root that was passed in or the
// top view found in xml.
if (root == null || !attachToRoot) {
result = temp;
}

这里的result最终就是我们的返回结果 , 那我们的参数就成功的得到了计算(因为有了父视图,match_parent被计算了大小,就是你父视图,即你的RecyclerView的大小),那我想要的效果就得到设置。