相比较于ViewPager,他新增了一些功能,
垂直方向的支持
ViewPager2可以在垂直方向上翻页,仅需要在布局文件添加一行代码
<androidx.viewpager2.widget.ViewPager2
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:orientation="vertical" />
这种场景应该极少,和多屏布局有滑动冲突
从右到左的支持
ViewPager2支持从右到左分页,仅需要在布局文件添加一行代码
<androidx.viewpager2.widget.ViewPager2
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:layoutDirection="rtl" />
这种场景应该也是极少的,滑动不太符合人操作的习惯,可能特殊需求时会用到
当页面数量发生变化时,可以通过notifyDataSetChanged()更新
Timer().schedule(timerTask {
runOnUiThread {
fragments.add(PlaceholderFragment.newInstance(3))
sectionsPagerAdapter.notifyDataSetChanged()
}
},3000)
DiffUtil
ViewPager2的构建基于RecyclerView,这意味着它可以使用DiffUtil类来更新数据集的变化,比如 :
val idsOld = items.createIdSnapshot()
performChanges()
val idsNew = items.createIdSnapshot()
DiffUtil.calculateDiff(object : DiffUtil.Callback() {
override fun getOldListSize(): Int = idsOld.size
override fun getNewListSize(): Int = idsNew.size
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int) =
idsOld[oldItemPosition] == idsNew[newItemPosition]
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int) =
areItemsTheSame(oldItemPosition, newItemPosition)
}, true).dispatchUpdatesTo(viewPager.adapter!!)
使用ViewPager2 + TabLayout
添加依赖
implementation 'com.google.android.material:material:1.1.0'
implementation "androidx.viewpager2:viewpager2:1.0.0"
布局
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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"
tools:context=".MainActivity">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:minHeight="?actionBarSize"
android:padding="@dimen/appbar_padding"
android:text="@string/app_name"
android:textAppearance="@style/TextAppearance.Widget.AppCompat.Toolbar.Title" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary" />
</com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
设置adapter
val sectionsPagerAdapter = SectionsPagerAdapter(this,fragments)
val viewPager: ViewPager2 = findViewById(R.id.view_pager)
viewPager.adapter = sectionsPagerAdapter
val tabs: TabLayout = findViewById(R.id.tabs)
TabLayoutMediator(tabs, viewPager) { tab, position ->
tab.text = "TAB ${(position + 1)}"
}.attach()
adapter
class SectionsPagerAdapter(
fm: FragmentActivity,
private val fragments: MutableList<Fragment>
)
: FragmentStateAdapter(fm) {
override fun getItemCount(): Int {
return fragments.size
}
override fun createFragment(position: Int): Fragment {
return fragments[position]
}
}
ViewPager2只有两个adapter基类可继承,分别为使用视图分页继承的RecyclerView.Adapter和使用fragment分页继承的FragmentStateAdapter