ViewPager2 ViewPager动态适配高度

ViewPager2

package com.autoviewpager.v2

import android.content.Context
import android.util.AttributeSet
import android.util.Log
import android.view.View
import android.widget.FrameLayout
import androidx.viewpager.widget.ViewPager
import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.viewpager2.widget.ViewPager2
import com.autoviewpager.AutoHeightPager

class AutoHeightV2Pager @JvmOverloads  constructor(context: android.content.Context, attrs: android.util.AttributeSet? = null) :FrameLayout(context, attrs) {

    var lastWidthMeasureSpec: Int = 0
    var currentHeight: Int = 0
    var lastPosition:Int = 0
    var isScrolling:Boolean = false

    var viewPager2: ViewPager2? = null


    override fun onFinishInflate() {
        super.onFinishInflate()

    }

    init {
        initialize(context, attrs)
    }

    fun initialize(context: Context, attrs: AttributeSet?) {
        viewPager2 = ViewPager2(context);
        viewPager2?.layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)

        viewPager2?.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback(){
            override fun onPageSelected(position: Int) {
                super.onPageSelected(position)

            }

            override fun onPageScrolled(
                position: Int,
                positionOffset: Float,
                positionOffsetPixels: Int
            ) {

                Log.e("vic_ddd","position = $position positionOffset = $positionOffset positionOffsetPixels=$positionOffsetPixels")

                if (positionOffset == 0f){
                    isScrolling = false
                    requestLayout()
                    return
                }

                val srcPosition = if (position>=lastPosition) position else position+1
                val destPosition = if (position>=lastPosition) position+1 else position
                val srcHeight = getViewHeight(srcPosition)
                val destHeight = getViewHeight(destPosition)

                Log.e("vic_ddd_2","srcHeight = $srcHeight  destHeight=$destHeight")

                val p =  if(position>=lastPosition) positionOffset else 1-positionOffset
                Log.e("vic_ddd_2","p = $p")
                Log.e("vic_ddd_2","destHeight - srcHeight = ${destHeight - srcHeight}")

                currentHeight =(srcHeight + (destHeight - srcHeight)*p).toInt()
                isScrolling = true
                requestLayout()
            }

            override fun onPageScrollStateChanged(state: Int) {
                if (state == ViewPager.SCROLL_STATE_IDLE){
                    isScrolling = false
                }
            }

        })

        attachViewToParent(this.viewPager2, 0, this.viewPager2?.getLayoutParams())

    }

    fun setAdapter(adapter: FragmentStateAdapter) {
        viewPager2?.adapter = adapter
    }

    private fun getViewHeight(position: Int): Int {
        val adapter = viewPager2?.adapter as? AutoHeightPager
        val view = adapter?.getView(position)

        view?.measure(lastWidthMeasureSpec, MeasureSpec.makeMeasureSpec(0,MeasureSpec.UNSPECIFIED))
        // view?.measure(lastWidthMeasureSpec, MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.EXACTLY))
        // view?.measure(lastWidthMeasureSpec, MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.AT_MOST))
        Log.e("vic_ddd_2","view?.measuredHeight = ${view?.measuredHeight } view = ${view}")
        return view?.measuredHeight ?: 0
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        lastWidthMeasureSpec = widthMeasureSpec
        var heightSpec = heightMeasureSpec
        if (isScrolling){
            Log.e("vic_ddd_2","currentHeight = $currentHeight")
            heightSpec = View.MeasureSpec.makeMeasureSpec(currentHeight, View.MeasureSpec.EXACTLY)
        }else{
            getViewHeight(viewPager2?.currentItem?:0).takeIf { it > 0 }?.let {
                heightSpec = View.MeasureSpec.makeMeasureSpec(it, View.MeasureSpec.EXACTLY)
            }
        }

        super.onMeasure(widthMeasureSpec, heightSpec)
    }


}

ViewPager

package com.autoviewpager

import android.util.Log
import android.view.View
import androidx.viewpager.widget.PagerAdapter
import androidx.viewpager.widget.ViewPager

interface AutoHeightPager {
    fun getView(position:Int):View?
}

class AutoHeightViewPager @JvmOverloads constructor(context: android.content.Context, attrs: android.util.AttributeSet? = null) : ViewPager(context, attrs) {

    var lastWidthMeasureSpec: Int = 0
    var currentHeight: Int = 0
    var lastPosition:Int = 0
    var isScrolling:Boolean = false

    init {
        addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
            override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
                Log.e("vic_ddd","position = $position positionOffset = $positionOffset positionOffsetPixels=$positionOffsetPixels")

                if (positionOffset == 0f){
                    isScrolling = false
                    requestLayout()
                    return
                }

                val srcPosition = if (position>=lastPosition) position else position+1
                val destPosition = if (position>=lastPosition) position+1 else position
                val srcHeight = getViewHeight(srcPosition)
                val destHeight = getViewHeight(destPosition)

                Log.e("vic_ddd_2","srcHeight = $srcHeight  destHeight=$destHeight")

                val p =  if(position>=lastPosition) positionOffset else 1-positionOffset
                Log.e("vic_ddd_2","p = $p")
                Log.e("vic_ddd_2","destHeight - srcHeight = ${destHeight - srcHeight}")

                currentHeight =(srcHeight + (destHeight - srcHeight)*p).toInt()
                isScrolling = true
                requestLayout()

            }

            override fun onPageSelected(p0: Int) {
            }

            override fun onPageScrollStateChanged(state: Int) {
                if (state == ViewPager.SCROLL_STATE_IDLE){
                    isScrolling = false
                }
            }
        })
    }

    private fun getViewHeight(position: Int): Int {
        val adapter = adapter as? AutoHeightPager
        val view = adapter?.getView(position)

       view?.measure(lastWidthMeasureSpec, MeasureSpec.makeMeasureSpec(0,MeasureSpec.UNSPECIFIED))
       // view?.measure(lastWidthMeasureSpec, MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.EXACTLY))
       // view?.measure(lastWidthMeasureSpec, MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.AT_MOST))
        Log.e("vic_ddd_2","view?.measuredHeight = ${view?.measuredHeight } view = ${view}")
        return view?.measuredHeight ?: 0
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        lastWidthMeasureSpec = widthMeasureSpec
        var heightSpec = heightMeasureSpec
        if (isScrolling){
            Log.e("vic_ddd_2","currentHeight = $currentHeight")
            heightSpec = View.MeasureSpec.makeMeasureSpec(currentHeight, View.MeasureSpec.EXACTLY)
        }else{
            getViewHeight(currentItem).takeIf { it > 0 }?.let {
                heightSpec = View.MeasureSpec.makeMeasureSpec(it, View.MeasureSpec.EXACTLY)
            }
        }

        super.onMeasure(widthMeasureSpec, heightSpec)
    }

    override fun setAdapter(adapter: PagerAdapter?) {
        super.setAdapter(adapter)
    }


}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值