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