欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2022-03-08 16:02:36
解决ViewPager设置高度无效问题,从源码角度分析并解决问题大家在开发中使用ViewPager做轮播之类的控件时,是不是会遇到当想设置它的高度时,怎么写都不生效,这其实是ViewPager的设计思想导致的,起初ViewPager就是为了做全屏的滑动切换,所以在它的源码中onMeasure中第一步就设置了自己的宽高源码中已经设定了默认使用父View的宽高,我们真实的需求其实大多都是希望ViewPager根据自己的子View高度来自适应自己的高度而我们遇到这个问题时,一般来说都是不知道问度娘…当我们...

大家在开发中使用ViewPager做轮播之类的控件时,是不是会遇到当想设置它的高度时,怎么写都不生效,这其实是ViewPager的设计思想导致的,起初ViewPager就是为了做全屏的滑动切换,所以在它的源码中onMeasure中第一步就设置了自己的宽高解决ViewPager设置高度无效问题,从源码角度分析并解决问题
源码中已经设定了默认使用父View的宽高,我们真实的需求其实大多都是希望ViewPager根据自己的子View高度来自适应自己的高度
而我们遇到这个问题时,一般来说都是不知道问度娘…
当我们去百度一下,发现查到的解决方案都是这样的
解决ViewPager设置高度无效问题,从源码角度分析并解决问题
但其实这都是治标不治本的,不能根据你的实际需求来随意更改它的高度,总的来说我们只需要自定义自己的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设置高度无效问题,从源码角度分析并解决问题
解决ViewPager设置高度无效问题,从源码角度分析并解决问题
以上就是我们的解决方案的全部内容了,其实只要我们用心看了源码,都可以从源码的设计方式中找到解决问题的方法。
感谢观看,如果有帮助到您,欢迎点赞、评论、分享,转发清注明出处,谢谢。

本文地址:https://blog.csdn.net/L0VE_Iris/article/details/107139730