ViewPager2 是 ViewPager 库的改进版本,可提供增强型功能并解决使用 ViewPager 时遇到的一些问题
ViewPager有两个弊端:1.不能关闭预加载;2.更新adapter不生效
我们在加载数据的时候,viewpager默认会帮我们预加载前后两个页面的数据,并且这2个view是不可见的。而目前ViewPager2对Fragment支持只能用FragmentStateAdapter,FragmentStateAdapter在遇到预加载时,只会创建Fragment对象,不会把Fragment真正的加入到布局中,所以自带懒加载效果
(1)垂直方向支持,可以通过设置 ViewPager2 元素的 android:orientation 属性为其启用垂直分页
(2)从右到左支持,系统会根据语言区域在适当的情况下自动启用 RTL 分页,也可以通过设置 ViewPager2 元素的 android:layoutDirection 属性为其手动启用 RTL 分页
(3)更高效的notifyDataSetChanged,在运行时动态修改 Fragment 集合,而 ViewPager2 会正确显示修改后的集合
(1)导入依赖:
implementation "com.google.android.material:material:1.2.1"
(2)activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabGravity="fill"
app:tabIndicatorColor="@android:color/holo_blue_light"
app:tabIndicatorHeight="2dp"
app:tabMode="fixed"
app:tabSelectedTextColor="@android:color/holo_blue_light"
app:tabTextColor="@android:color/black" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
LinearLayout>
(3)MainActivity
class MainActivity : AppCompatActivity() {
private var fragmentList: MutableList<Fragment>? = null
private val title = arrayOf("海贼王", "火影忍者", "七龙珠")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
init()
}
private fun init() {
fragmentList = ArrayList()
fragmentList!!.add(OneFragment())
fragmentList!!.add(TwoFragment())
fragmentList!!.add(ThreeFragment())
viewPager.adapter = MyFragmentStateAdapter(this, fragmentList!!)
viewPager.setPageTransformer(ZoomOutPageTransformer())//设置页面切换的动画
//TabLayout与ViewPager2联动
TabLayoutMediator(tabLayout, viewPager) {
tab, position ->
tab.text = title[position]
}.attach()
}
}
可以设置viewPager.isUserInputEnabled = false禁用页面滑动
TabLayout可以设置app:tabIndicatorFullWidth=“false”,使其下划线的宽度随着字的宽改变而改变
(4)MyFragmentStateAdapter
class MyFragmentStateAdapter(fragmentActivity: FragmentActivity, private val list: List<Fragment>) :
FragmentStateAdapter(fragmentActivity) {
override fun createFragment(position: Int): Fragment {
return list[position]
}
override fun getItemCount(): Int {
return list.size
}
}
(5)Fragment切换的动画
private const val MIN_SCALE = 0.85f
private const val MIN_ALPHA = 0.5f
class ZoomOutPageTransformer : ViewPager2.PageTransformer {
override fun transformPage(view: View, position: Float) {
view.apply {
val pageWidth = width
val pageHeight = height
when {
position < -1 -> {
alpha = 0f
}
position <= 1 -> {
val scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position))
val vertMargin = pageHeight * (1 - scaleFactor) / 2
val horzMargin = pageWidth * (1 - scaleFactor) / 2
translationX = if (position < 0) {
horzMargin - vertMargin / 2
} else {
horzMargin + vertMargin / 2
}
scaleX = scaleFactor
scaleY = scaleFactor
alpha = (MIN_ALPHA +
(((scaleFactor - MIN_SCALE) / (1 - MIN_SCALE)) * (1 - MIN_ALPHA)))
}
else -> {
alpha = 0f
}
}
}
}
}
如果你想实现底部导航栏,用法也差不多
修改布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabGravity="fill"
app:tabIndicatorColor="@android:color/holo_blue_light"
app:tabIndicatorHeight="2dp"
app:tabMode="fixed"
app:tabSelectedTextColor="@android:color/holo_blue_light"
app:tabTextColor="@android:color/black" />
LinearLayout>
修改Activity的代码
class BottomActivity : AppCompatActivity() {
private var fragmentList: MutableList<Fragment>? = null
private val title = arrayOf("首页", "位置", "我的")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_bottom)
init()
}
private fun init() {
fragmentList = ArrayList()
fragmentList!!.add(OneFragment())
fragmentList!!.add(TwoFragment())
fragmentList!!.add(ThreeFragment())
//设置底部导航图标
val icon = arrayListOf(
ContextCompat.getDrawable(this, R.drawable.home_grey)!!,
ContextCompat.getDrawable(this, R.drawable.add_grey)!!,
ContextCompat.getDrawable(this, R.drawable.me_grey)!!
)
val iconSelected = arrayListOf(
ContextCompat.getDrawable(this, R.drawable.home_blue)!!,
ContextCompat.getDrawable(this, R.drawable.add_blue)!!,
ContextCompat.getDrawable(this, R.drawable.me_blue)!!
)
view_pager.adapter = MyFragmentStateAdapter(this, fragmentList!!)
view_pager.setPageTransformer(ZoomOutPageTransformer())
tab_layout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab?) {
tab!!.icon = iconSelected[tab.position]
}
override fun onTabUnselected(tab: TabLayout.Tab?) {
tab!!.icon = icon[tab.position]
}
override fun onTabReselected(tab: TabLayout.Tab?) {
}
})
view_pager.isUserInputEnabled = false //禁用页面滑动
//TabLayout与ViewPager2联动
TabLayoutMediator(tab_layout, view_pager) {
tab, position ->
tab.text = title[position]
tab.icon = icon[position]
}.attach()
}
}