测量 ViewPager [英] Measuring a ViewPager

查看:10
本文介绍了测量 ViewPager的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义 ViewGroup,它有一个子 ViewPager.ViewPager 由 PagerAdapter 提供,该 LinearLayoutViewPager 提供 LayoutParamsWRAP_CONTENT 高度和宽度.

I have a custom ViewGroup that has a child ViewPager. The ViewPager is fed by a PagerAdapter that provides a LinearLayout to the ViewPager which has LayoutParams of WRAP_CONTENT on both height and width.

视图显示正确,但是当在 ViewPager 上调用 child.measure() 方法时,它不会返回 LinearLayout 的实际尺寸,但似乎会填满所有剩余空间.

The view displays correctly but when the child.measure() method is called on the ViewPager it does not return the actual dimensions of the LinearLayout but seems to fill all the remaining space.

任何想法为什么会发生这种情况以及如何修改它?

Any ideas why this is happening and how to amend it?

推荐答案

我对接受的答案不太满意(也不对评论中的 pre-inflate-all-views 解决方案),所以我整理了一个 ViewPager 从第一个可用的子节点获取高度.它通过进行第二次测量来做到这一点,允许您窃取第一个孩子的身高.

I wasn't very happy with the accepted answer (nor with the pre-inflate-all-views solution in the comments), so I put together a ViewPager that takes its height from the first available child. It does this by doing a second measurement pass, allowing you to steal the first child's height.

更好的解决方案是在 android.support.v4.view 包中创建一个新类,该类实现更好的 onMeasure 版本(可以访问包-populate())

A better solution would be to make a new class inside the android.support.v4.view package that implements a better version of onMeasure (with access to package-visible methods like populate())

不过,就目前而言,下面的解决方案很适合我.

For the time being, though, the solution below suits me fine.

public class HeightWrappingViewPager extends ViewPager {

    public HeightWrappingViewPager(Context context) {
        super(context);
    }

    public HeightWrappingViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        boolean wrapHeight = MeasureSpec.getMode(heightMeasureSpec) 
                == MeasureSpec.AT_MOST;

        if(wrapHeight) {
            /**
             * The first super.onMeasure call made the pager take up all the 
             * available height. Since we really wanted to wrap it, we need 
             * to remeasure it. Luckily, after that call the first child is 
             * now available. So, we take the height from it. 
             */

            int width = getMeasuredWidth(), height = getMeasuredHeight();

            // Use the previously measured width but simplify the calculations
            widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);

            /* If the pager actually has any children, take the first child's 
             * height and call that our own */ 
            if(getChildCount() > 0) {
                View firstChild = getChildAt(0);

                /* The child was previously measured with exactly the full height.
                 * Allow it to wrap this time around. */
                firstChild.measure(widthMeasureSpec, 
                        MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST));

                height = firstChild.getMeasuredHeight();
            }

            heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);

            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }
}

这篇关于测量 ViewPager的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆