关于ViewPager的wrap_content无效的问题
主要需要了解2个地方
你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。
ViewPager的onMeasure方法
ViewPager的onMeasure方法中直接设置死了宽高,所有都没有子View的事儿:
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(getDefaultSize(0, widthMeasureSpec),
getDefaultSize(0, heightMeasureSpec));
...
----------解决办法---------------
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int height = 0;
//下面遍历所有child的高度
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
// 获取当前view的params的属性,
// 这里要配合inflate(layout,parent,false),否则也是无效的
LayoutParams layoutParams = (LayoutParams) child.getLayoutParams();
// 获取高度 与 mode
final int heightMode;
int childSpecSize;
if (layoutParams.height >= 0) {
heightMode = MeasureSpec.EXACTLY;
childSpecSize = layoutParams.height;
} else {
childSpecSize = 0;
heightMode = MeasureSpec.UNSPECIFIED;
}
// 开始进行测量view
child.measure(widthMeasureSpec,
MeasureSpec.makeMeasureSpec(childSpecSize, heightMode));
// 获取测量后view的高度
int h = child.getMeasuredHeight();
//采用最大的view的高度。
if (h > height) {
height = h;
}
}
// 将最大的高度进行测量,然后得到的结果放到父类中
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height,
MeasureSpec.EXACTLY);
// 最后在调用父类的方法,然后里面在执行 setMeasuredDimension
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
正常看下LinearLayout RelativeLayout的onMeasure()方法,都是遍历完所有的child然后才去调用这个方法setMeasuredDimension,而ViewPager却上来就直接调用这个方法;所以导致了child在加载到界面的时候是全屏显示
LayoutInflater.from(container.getContext()).inflate(layout,parent,false)
这个方法一般都会使用,但是我们在加载的时候就需要考虑后面的2个参数的含义;需要进入源码进行查看
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
// 创建view对象的时候,3个参数都要进行添加
View view = LayoutInflater.from(container.getContext())
.inflate(mList.get(position),container,false);
container.addView(view);
return view;
}
----------------------------
XmlResourceParser parser = res.getLayout(resource);
try {
// 看这个方法的内部
return inflate(parser, root, attachToRoot);
}
------------------------------
...
// 看到这个对象,里面可以拿到布局的宽高等信息
ViewGroup.LayoutParams params = null;
if (root != null) {
// 创建出来
params = root.generateLayoutParams(attrs);
if (!attachToRoot) {
// 然后将创建的view设置对应的属性
temp.setLayoutParams(params);
}
}
...
所以我们在调用inflate的时候需要将3个参数都进行传入,inflate(layout,container,false);