电动工具咋在网上做网站,搜索更多网页内容,网站建设费交文化事业,虚拟主机可以做几个网站需求
在项目中#xff0c;我们常常遇到需要动态调整 ViewPager 的高度#xff0c;以适应其内容大小的需求。默认情况下#xff0c;ViewPager 的高度是固定的#xff0c;无法根据每个页面的内容高度进行调整。这会导致在内容高度不一致时#xff0c;出现不必要的空白区域或…需求
在项目中我们常常遇到需要动态调整 ViewPager 的高度以适应其内容大小的需求。默认情况下ViewPager 的高度是固定的无法根据每个页面的内容高度进行调整。这会导致在内容高度不一致时出现不必要的空白区域或者内容被裁剪的情况。为了解决这个问题我们设计了一个 AutoHeightViewPager能够根据当前显示页面的内容高度动态调整自身的高度保证内容完整且没有多余的空白。
效果 实现思路
1. 动态高度调整
首先我们需要一个自定义的 ViewPager 类 AutoHeightViewPager这个类可以根据当前页面的内容高度来动态调整自身的高度。通过重写 onMeasure 方法可以在滑动过程中动态计算页面的高度并调整布局。
2. 监听页面滑动事件
为了平滑过渡我们需要监听页面的滑动过程并计算滑动比例将当前页面的高度与下一个页面的高度按比例过渡实现平滑过渡效果。
3. 自定义 Adapter
自定义的 PagerAdapter 必须实现一个接口 AutoHeightPager用于获取指定位置页面的 View这样我们可以测量页面内容的高度。
实现代码
1. AutoHeightViewPager
package com.yxlh.androidxy.demo.ui.viewpager.vpimport android.content.Context
import android.util.AttributeSet
import android.view.View
import androidx.viewpager.widget.PagerAdapter
import androidx.viewpager.widget.ViewPagerinterface AutoHeightPager {fun getView(position: Int): View?
}class AutoHeightViewPager JvmOverloads constructor(context: Context,attrs: AttributeSet? null
) : ViewPager(context, attrs) {private var lastWidthMeasureSpec: Int 0private var currentHeight: Int 0private var lastPosition: Int 0private var isScrolling: Boolean falseinit {addOnPageChangeListener(object : SimpleOnPageChangeListener() {override fun onPageScrolled(position: Int,positionOffset: Float,positionOffsetPixels: Int) {if (positionOffset 0f) {isScrolling falserequestLayout()return}val srcPosition if (position lastPosition) position else position 1val destPosition if (position lastPosition) position 1 else positionval srcHeight getViewHeight(srcPosition)val destHeight getViewHeight(destPosition)currentHeight (srcHeight (destHeight - srcHeight) *if (position lastPosition) positionOffset else 1 - positionOffset).toInt()isScrolling truerequestLayout()}override fun onPageScrollStateChanged(state: Int) {if (state SCROLL_STATE_IDLE) {lastPosition currentItem}}})}override fun setAdapter(adapter: PagerAdapter?) {require(adapter null || adapter is AutoHeightPager) { PagerAdapter must implement AutoHeightPager. }super.setAdapter(adapter)}private fun getViewHeight(position: Int): Int {val adapter adapter as? AutoHeightPager ?: return 0return run {val view adapter.getView(position) ?: return 0view.measure(lastWidthMeasureSpec,MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED))view.measuredHeight}}override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {lastWidthMeasureSpec widthMeasureSpecvar heightSpec heightMeasureSpecif (isScrolling) {heightSpec MeasureSpec.makeMeasureSpec(currentHeight, MeasureSpec.EXACTLY)} else {getViewHeight(currentItem).takeIf { it 0 }?.let {heightSpec MeasureSpec.makeMeasureSpec(it, MeasureSpec.EXACTLY)}}super.onMeasure(widthMeasureSpec, heightSpec)}
}2. AutoHeightPagerAdapter
package com.yxlh.androidxy.demo.ui.viewpagerimport android.view.View
import android.view.ViewGroup
import androidx.viewpager.widget.PagerAdapter
import com.yxlh.androidxy.demo.ui.viewpager.vp.AutoHeightPagerclass AutoHeightPagerAdapter : PagerAdapter(), AutoHeightPager {private val viewList mutableListOfView()override fun instantiateItem(container: ViewGroup, position: Int): Any {val view viewList[position]val parent view.parent as? ViewGroupparent?.removeView(view)container.addView(view)return view}override fun destroyItem(container: ViewGroup, position: Int, object: Any) {container.removeView(object as View)}fun setViews(views: ListView) {viewList.clear()viewList.addAll(views)notifyDataSetChanged()}override fun getView(position: Int): View? {return viewList.getOrNull(position)}override fun getCount(): Int {return viewList.size}override fun isViewFromObject(view: View, object: Any): Boolean {return view object}
}3. Activity 代码
package com.yxlh.androidxy.demo.ui.viewpagerimport android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import com.yxlh.androidxy.R
import com.yxlh.androidxy.demo.ui.viewpager.vp.AutoHeightViewPagerclass VpActivity : AppCompatActivity() {private var mAutoHeightVp: AutoHeightViewPager? nullprivate var mAdapter: AutoHeightPagerAdapter? nulloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_vp)val viewList: MutableListView ArrayList()viewList.add(LayoutInflater.from(this).inflate(R.layout.view_demo_1, null))viewList.add(LayoutInflater.from(this).inflate(R.layout.view_demo_2, null))mAutoHeightVp findViewById(R.id.viewpager)mAutoHeightVp?.setAdapter(AutoHeightPagerAdapter().also { mAdapter it })mAdapter?.setViews(viewList)mAutoHeightVp?.setCurrentItem(1)}
}4. 布局 XML
?xml version1.0 encodingutf-8?
androidx.constraintlayout.widget.ConstraintLayoutxmlns:androidhttp://schemas.android.com/apk/res/androidxmlns:apphttp://schemas.android.com/apk/res-autoandroid:layout_widthmatch_parentandroid:layout_heightmatch_parentandroidx.core.widget.NestedScrollViewandroid:layout_widthmatch_parentandroid:layout_heightwrap_contentapp:layout_constraintTop_toTopOfparentLinearLayoutandroid:layout_widthmatch_parentandroid:layout_heightmatch_parentandroid:orientationverticalcom.yxlh.androidxy.demo.ui.viewpager.vp.AutoHeightViewPagerandroid:idid/viewpagerandroid:layout_widthmatch_parentandroid:layout_heightwrap_content /ImageViewandroid:layout_widthmatch_parentandroid:layout_heightwrap_contentandroid:adjustViewBoundstrueandroid:scaleTypefitXYandroid:srcdrawable/vp_content //LinearLayout/androidx.core.widget.NestedScrollView/androidx.constraintlayout.widget.ConstraintLayout总结
通过自定义 ViewPager 的动态高度适配功能我们可以解决内容高度不一致导致的布局问题。这种方案可以适应不同页面内容的高度变化实现平滑的过渡效果非常适用于动态内容展示的场景。