关于ViewPager的wrap_content无效的问题

关于ViewPager的wrap_content无效的问题

  • 主要需要了解2个地方
    • ViewPager的onMeasure方法
    • LayoutInflater.from(container.getContext()).inflate(layout,parent,false)

主要需要了解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);

你可能感兴趣的:(自定义View,源码分析,viewpager)