原文地址:itnext.io/android-vie…html
ViewPager2是在2019年Google I/O大會推出的用來替代ViewPager的,它包含了一些新的特性以及加強了UI和代碼的體驗。java
ViewPager2是由RecyclerView支持的ViewGroup,ViewPager2須要一個adapter用來顯示內容,adapter能夠是RecyclerView.Adapter 或者FragmentStateAdapter。android
本文主要介紹ViewPager2的基本使用以及配合TabLayout的使用方法。git
ViewPager2包含在AndroidX library of JetPack中,因此須要單獨引入。github
dependencies {
// For the latest version number of ViewPager2, please refer to the official page.
// Link: https://developer.android.com/jetpack/androidx/releases/viewpager2
implementation 'androidx.viewpager2:viewpager2:1.0.0-alpha04'
}
複製代碼
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="240dp"/>
</LinearLayout>
複製代碼
class DemoViewPagerAdapter : RecyclerView.Adapter<DemoViewPagerAdapter.EventViewHolder>() {
val eventList = listOf("0", "1", "2")
// Layout "layout_demo_viewpager2_cell.xml" will be defined later
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
EventViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.layout_demo_viewpager2_cell, parent, false))
override fun getItemCount() = eventList.count()
override fun onBindViewHolder(holder: EventViewHolder, position: Int) {
(holder.view as? TextView)?.also{
it.text = "Page " + eventList.get(position)
val backgroundColorResId = if (position % 2 == 0) R.color.blue else R.color.orange)
it.setBackgroundColor(ContextCompat.getColor(it.context, backgroundColorResId))
}
}
class EventViewHolder(val view: View) : RecyclerView.ViewHolder(view)
}
複製代碼
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="20sp"
android:gravity="center"/>
複製代碼
class ViewPager2Activity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.layout_view_pager_demo)
viewpager.adapter = DemoViewPagerAdapter()
}
}
複製代碼
TabLayout 沒法與 ViewPager2綁定bash
可是在StackOverFlow中找到了解決方案,咱們能夠使用TabLayoutMediator實現TabLayout與ViewPager2的綁定。app
TabLayoutMediator不能直接使用,因此須要拷貝一份出來,根據代碼註釋可知TabLayoutMediator只能在初始化以後才能調用attach方法:ide
class ViewPager2Activity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_view_pager2)
// Must be declared before TabLayoutMediator.attach()
viewpager.adapter = DemoViewPagerAdapter()
TabLayoutMediator(tabLayout, viewpager, object : TabLayoutMediator.OnConfigureTabCallback {
override fun onConfigureTab(tab: TabLayout.Tab, position: Int) {
// Styling each tab here
tab.setText("Tab $position")
}
}).attach()
}
}
複製代碼
TabLayoutMediator.OnConfigureTabCallback是一個用戶友好的方法,在初始化TabLayout.Tab或數據更改是調用:佈局
ViewPager2能夠接受RecyclerView Adapter 和 FragmentStateAdapter,二者的區別就是RecyclerView Adapter inflate View,而FragmentStateAdapter inflate Fragment。post
當ViewPager2中的每一個頁面用於顯示靜態信息時,當必須考慮頁面的生命週期時,能夠使用FragmentStateAdapter。
TabLayout與舊版ViewPager集成在一塊兒很簡單,只需將其添加爲ViewPager的子項,並按設置layout_gravity屬性就能夠了。
<android.support.v4.view.ViewPager
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top" />
</android.support.v4.view.ViewPager>
複製代碼
然而,ViewPager2不接受TabLayout做爲子View綁定。