本文章内容主要写的是viewpager2在Activity和Fragment中的使用,TabLayout+ViewPager2
ViewPager2 从出来到现在已经有一段时间了,它修复了 ViewPager 常见的一些 bug,以及支持竖直方法和 RTL 。
ViewPager2 只能用FragmentStateAdapter,FragmentStateAdapter在遇到预加载时,只创建Fragment对象,不会把Fragment真正的加入到布局中,自带懒加载效果。而ViewPager不能关闭预加载。
戳链接查看官方文档 ViewPager2
示例Demo链接 ViewPager2 Demo
ViewPager | ViewPager2 |
---|---|
FragmentPagerAdapter继承PagerAdapter | FragmentStateAdapter继承RecyclerView.Adapter |
addOnPageChangeListener | registerOnPageChangeCallback |
android:layoutDirection="rtl"设置为从右到左滑动 | |
android:orientation=“vertical” 控制横向和纵向滑动 | |
控制ViewPager2能否滑动(setUserInputEnabled、isUserInputEnabled) |
代码如下(示例):
[ 目前经过库迁移material库已包含RecyclerView和ViewPager2,无需单独引入其他依赖库 ]
implementation "com.google.android.material:material:1.3.0-alpha03"
代码如下(示例):
<androidx.constraintlayout.widget.ConstraintLayout 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:background="@color/white"
tools:context=".MainActivity">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:layout_width="@dimen/dimen_0_dp"
android:layout_height="@dimen/dimen_25_dp"
android:layout_marginStart="@dimen/dimen_16_dp"
android:layout_marginTop="@dimen/dimen_16_dp"
android:layout_marginEnd="@dimen/dimen_16_dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tabBackground="@drawable/tab_background"
app:tabIndicatorColor="@color/white"
app:tabIndicatorFullWidth="false"
app:tabIndicatorHeight="@dimen/dimen_0_dp"
app:tabRippleColor="@android:color/transparent"
app:tabSelectedTextColor="@color/white"
app:tabTextAppearance="@style/TabTextAppearance" />
<View
android:id="@+id/line1"
android:layout_width="@dimen/dimen_0_dp"
android:layout_height="@dimen/dimen_1_px"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tabLayout"
android:layout_marginTop="@dimen/dimen_5_dp"
android:background="@color/line_color"/>
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewPager"
android:layout_width="@dimen/dimen_0_dp"
android:layout_height="@dimen/dimen_0_dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/line1"
android:layout_marginTop="@dimen/dimen_5_dp"/>
androidx.constraintlayout.widget.ConstraintLayout>
代码如下(示例):
viewPager.adapter = ViewPagerAdapter(this)
viewPager.offscreenPageLimit = 4
val titles = mutableListOf("Tab1", "Tab2","Tab3","Tab4",)
//将tabLayout与viewPager绑定
TabLayoutMediator(tabLayout, viewPager,
TabLayoutMediator.TabConfigurationStrategy {
tab, position ->
tab.text = titles[position]
}).attach()
在Activity中使用时,FragmentStateAdapter的代码如下(示例):
//在Activity中使用
class ViewPagerAdapter(fragmentActivity: FragmentActivity) :
FragmentStateAdapter(fragmentActivity) {
private val fragments = mutableListOf(
Tab1Fragment(), Tab2Fragment(),
Tab3Fragment(), Tab4Fragment()
)
override fun getItemCount(): Int {
return fragments.size
}
override fun createFragment(position: Int): Fragment {
return fragments[position]
}
}
在Fragment中使用时,FragmentStateAdapter的代码如下(示例):
//在Fragmet中使用
class FragmentViewPagerAdapter(
private val fragments: MutableList<Fragment>,
fragment: Fragment
) : FragmentStateAdapter(fragment) {
override fun getItemCount(): Int {
return fragments.size
}
override fun createFragment(position: Int): Fragment {
return fragments[position]
}
}
FragmentStateAdapter提供了三个构造函数,代码如下:
方法一:
/**
* @param fragmentActivity if the {@link ViewPager2} lives directly in a
* {@link FragmentActivity} subclass.
*
* @see FragmentStateAdapter#FragmentStateAdapter(Fragment)
* @see FragmentStateAdapter#FragmentStateAdapter(FragmentManager, Lifecycle)
*/
public FragmentStateAdapter(@NonNull FragmentActivity fragmentActivity) {
this(fragmentActivity.getSupportFragmentManager(), fragmentActivity.getLifecycle());
}
方法二:
/**
* @param fragment if the {@link ViewPager2} lives directly in a {@link Fragment} subclass.
*
* @see FragmentStateAdapter#FragmentStateAdapter(FragmentActivity)
* @see FragmentStateAdapter#FragmentStateAdapter(FragmentManager, Lifecycle)
*/
public FragmentStateAdapter(@NonNull Fragment fragment) {
this(fragment.getChildFragmentManager(), fragment.getLifecycle());
}
方法三:
/**
* @param fragmentManager of {@link ViewPager2}'s host
* @param lifecycle of {@link ViewPager2}'s host
*
* @see FragmentStateAdapter#FragmentStateAdapter(FragmentActivity)
* @see FragmentStateAdapter#FragmentStateAdapter(Fragment)
*/
public FragmentStateAdapter(@NonNull FragmentManager fragmentManager,
@NonNull Lifecycle lifecycle) {
mFragmentManager = fragmentManager;
mLifecycle = lifecycle;
super.setHasStableIds(true);
}
示例中的 tab_background
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/shape_green"
android:state_selected="true" />
<item android:drawable="@color/white"
android:state_focused="false"
android:state_selected="false" />
selector>
示例中的 TabTextAppearance
<style name="TabTextAppearance" parent="TextAppearance.Design.Tab">
- "android:textSize"
>@dimen/text_size_13_sp
- "android:textColor">@color/colorPrimary
- "textAllCaps">true
style>