解决ViewPager设置高度无效问题,从源码角度分析并解决问题

大家在开发中使用ViewPager做轮播之类的控件时,是不是会遇到当想设置它的高度时,怎么写都不生效,这其实是ViewPager的设计思想导致的,起初ViewPager就是为了做全屏的滑动切换,所以在它的源码中onMeasure中第一步就设置了自己的宽高解决ViewPager设置高度无效问题,从源码角度分析并解决问题_第1张图片
源码中已经设定了默认使用父View的宽高,我们真实的需求其实大多都是希望ViewPager根据自己的子View高度来自适应自己的高度
而我们遇到这个问题时,一般来说都是不知道问度娘…
当我们去百度一下,发现查到的解决方案都是这样的
解决ViewPager设置高度无效问题,从源码角度分析并解决问题_第2张图片
但其实这都是治标不治本的,不能根据你的实际需求来随意更改它的高度,总的来说我们只需要自定义自己的ViewPager重写它的onMeasure,在onMeasure中控制ViewPager的高度与它的子View高度保持一致就可以了,
接下来就使用我们的方案,这里我们使用的是kotlin写的

class MyViewPager(context: Context) :ViewPager(context) {

    constructor(context: Context , attributeSet: AttributeSet) : this(context)

    constructor(context: Context , attributeSet: AttributeSet , style : Int) : this(context)

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {

        var maxHeight = 0
        //循环子度量View的高度,取最大值,作为ViewPager的高度
        for (i in 0 until childCount){
            var childView = getChildAt(i)

            var childLP = childView.layoutParams

            var childHeightSpec = getChildMeasureSpec(heightMeasureSpec, paddingTop + paddingBottom, childLP.height)

            childView.measure(widthMeasureSpec,childHeightSpec)

            maxHeight = Math.max(maxHeight,childView.measuredHeight)

        }
        
        val mHeightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.EXACTLY);

        super.onMeasure(widthMeasureSpec, mHeightMeasureSpec)
    }

}

还需要注意的一点是,在我们的PagerAdapter中需要重写instantiateItem函数加载ViewPager中自己的item布局

override fun instantiateItem(container: ViewGroup, position: Int): Any {

            val view = LayoutInflater.from(this@PagerActiivty).inflate(R.layout.pager_item,container,false)

            container.addView(view)
            return view
        }

加载布局时必须使用三参数的LayoutInflater.inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot)
这是因为在源码中root!=null且attachToRoot = false时,才会设置布局的LayoutParam,只有这样在自定义的ViewPager中才能拿到子View的LayouParam去获取子View的高度
解决ViewPager设置高度无效问题,从源码角度分析并解决问题_第3张图片
解决ViewPager设置高度无效问题,从源码角度分析并解决问题_第4张图片
以上就是我们的解决方案的全部内容了,其实只要我们用心看了源码,都可以从源码的设计方式中找到解决问题的方法。
感谢观看,如果有帮助到您,欢迎点赞、评论、分享,转发清注明出处,谢谢。

你可能感兴趣的:(自定义view)