欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

ViewPager2,用起来!

程序员文章站 2022-03-21 17:14:23
一、缘起:ViewPager2推出已经有一段时间了,而且官方推出了稳定版本Version 1.0.0,相比ViewPager增加了很多优势,是时候用起来了。二、优势1、垂直方向支持ViewPager2 支持垂直分页

一、缘起:

ViewPager2推出已经有一段时间了,而且官方推出了稳定版本Version 1.0.0,相比ViewPager增加了很多优势,是时候用起来了。

二、优势

1、垂直方向支持
  • ViewPager2 支持垂直分页
   <androidx.viewpager2.widget.ViewPager2
            android:id="@+id/viewpager_two"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"/>
  • 代码动态设置方式
// 水平方向
viewpager_two.orientation=ViewPager2.ORIENTATION_HORIZONTAL
// 垂直方向
viewpager_two.orientation=ViewPager2.ORIENTATION_VERTICAL

ps:之前使用VerticalViewpager现在可以改为ViewPager2了

2、从右到左支持
  • 默认为从左到右滑动方向,可以通过设置layoutDirection="rtl"设置为从右到左滑动
  <androidx.viewpager2.widget.ViewPager2
            android:id="@+id/viewpager_two"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
             android:layoutDirection="rtl"/>
3、可修改的 Fragment 集合

ViewPager2 支持对可修改的 Fragment 集合进行分页浏览,在底层集合发生更改时调用 notifyDatasetChanged() 来更新界面。

4、DiffUtil

ViewPager2 在 RecyclerView 的基础上构建而成,这意味着它可以访问 DiffUtil 实用程序类。这一点带来了多项优势,但最突出的一项是,这意味着 ViewPager2 对象本身会利用 RecyclerView 类中的数据集更改动画。

三、使用实例

1、添加依赖
  • build.gradle中
dependencies {
    implementation "androidx.viewpager2:viewpager2:1.0.0"
}
2、水平滑动 不指定方向为水平滑动
  • 水平滑动从左到右方向
  • xml文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    <androidx.viewpager2.widget.ViewPager2
            android:id="@+id/viewpager_two"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />
</LinearLayout>
  • adapter
class ViewpagerTwoAdapter : RecyclerView.Adapter<ViewpagerTwoAdapter.MyHolder>() {

    private val imgArray = intArrayOf(R.drawable.dog_01, R.drawable.dog_02, R.drawable.dog_03)
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyHolder {
        return MyHolder(
            LayoutInflater.from(parent.context).inflate(R.layout.item_view_pager2, parent, false)
        )
    }

    override fun getItemCount(): Int {
        return 10
    }

    override fun onBindViewHolder(holder: MyHolder, position: Int) {
        holder.ivItem.setImageResource(imgArray[position % imgArray.size])
    }


    class MyHolder(view: View) : RecyclerView.ViewHolder(view) {
        val ivItem: ImageView = view.findViewById(R.id.iv_item)
    }
}
  • 效果图
    ViewPager2,用起来!

  • 水平滑动从右到左方向

  • 添加方向指定 android:layoutDirection=“rtl”

  <androidx.viewpager2.widget.ViewPager2
            android:id="@+id/viewpager_two"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:layoutDirection="rtl"
            />
  • 效果图
    ViewPager2,用起来!
3、垂直方向滑动
  • 只需指定android:orientation="vertical"即可
 <androidx.viewpager2.widget.ViewPager2
            android:id="@+id/viewpager_two"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:orientation="vertical"/>
  • 效果图
    ViewPager2,用起来!
4、结合Fragment使用
  • activity代码
 // 结合fragment使用
         viewpager_two.adapter = FragmentViewPagerTwoAdapter(this)
  • adapter 继承FragmentStateAdapter
class FragmentViewPagerTwoAdapter(frag:FragmentActivity) :FragmentStateAdapter(frag){

    override fun getItemCount(): Int {
        return 5
    }

    override fun createFragment(position: Int): Fragment {
        return NormalFragment()
    }
}
  • Fragment代码
class NormalFragment :Fragment(){
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_normal, container, false)
    }
}
  • fragment_normal xml文件
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <ImageView
                android:id="@+id/iv_fragment_normal"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:src="@drawable/dog_01"/>
</androidx.constraintlayout.widget.ConstraintLayout>
  • 效果图
    ViewPager2,用起来!

Fragment也可以设置为垂直滑动和从右到左水平滑动,只需根据需要设置orientation和layoutDirection即可

5、结合TabLayout使用
  • 添加依赖
implementation "com.google.android.material:material:1.1.0-beta01"
  • xml文件
<?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/tab_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

    <androidx.viewpager2.widget.ViewPager2
            android:id="@+id/viewpager_two"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />
</LinearLayout>
  • activity调用代码
 // 结合tableLayout使用
        TabLayoutMediator(tab_layout, viewpager_two) { tab, position ->
            tab.text = "Tab ${(position + 1)}"
        }.attach()

一定要调用attach()方法才起作用

  • 效果图
    ViewPager2,用起来!
6、实现ViewPager2.PageTransformer自定义切换效果,设置切换效果
放大进入效果
  • activity代码
 viewpager_two.setPageTransformer(ZoomPagerTransformer())
  • ZoomPagerTransformer
private const val MIN_SCALE = 0.85f
private const val MIN_ALPHA = 0.5f
class ZoomPagerTransformer :ViewPager2.PageTransformer{
    override fun transformPage(view: View, position: Float) {
        view.apply {
            val pageWidth = width
            val pageHeight = height
            when {
                position < -1 -> { // [-Infinity,-1)
                    // This page is way off-screen to the left.
                    alpha = 0f
                }
                position <= 1 -> { // [-1,1]
                    // Modify the default slide transition to shrink the page as well
                    val scaleFactor = MIN_SCALE.coerceAtLeast(1 - 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
                    }

                    // Scale the page down (between MIN_SCALE and 1)
                    scaleX = scaleFactor
                    scaleY = scaleFactor

                    // Fade the page relative to its size.
                    alpha = (MIN_ALPHA +
                            (((scaleFactor - MIN_SCALE) / (1 - MIN_SCALE)) * (1 - MIN_ALPHA)))
                }
                else -> { // (1,+Infinity]
                    // This page is way off-screen to the right.
                    alpha = 0f
                }
            }
        }
    }

}
  • 效果图

ViewPager2,用起来!

层次进入效果
  • activity代码
 viewpager_two.setPageTransformer(DepthPageTransformer())
  • DepthPageTransformer
private const val MIN_SCALE = 0.75f

class DepthPageTransformer : ViewPager2.PageTransformer {

    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    override fun transformPage(view: View, position: Float) {
        view.apply {
            val pageWidth = width
            when {
                position < -1 -> { // [-Infinity,-1)
                    // This page is way off-screen to the left.
                    alpha = 0f
                }
                position <= 0 -> { // [-1,0]
                    // Use the default slide transition when moving to the left page
                    alpha = 1f
                    translationX = 0f
                    translationZ = 0f
                    scaleX = 1f
                    scaleY = 1f
                }
                position <= 1 -> { // (0,1]
                    // Fade the page out.
                    alpha = 1 - position

                    // Counteract the default slide transition
                    translationX = pageWidth * -position
                    // Move it behind the left page
                    translationZ = -1f

                    // Scale the page down (between MIN_SCALE and 1)
                    val scaleFactor = (MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position)))
                    scaleX = scaleFactor
                    scaleY = scaleFactor
                }
                else -> { // (1,+Infinity]
                    // This page is way off-screen to the right.
                    alpha = 0f
                }
            }
        }
    }
}
  • 效果图
    ViewPager2,用起来!
使用CompositePageTransformer实现多个transformer合并使用
  • activity代码
 // 多个transformer结合使用
        val compositePageTransformer = CompositePageTransformer()
        compositePageTransformer.addTransformer(DepthPageTransformer())
        // marginTransformer
        compositePageTransformer.addTransformer(MarginPageTransformer(10))
        viewpager_two.setPageTransformer(compositePageTransformer)
  • 效果图
    ViewPager2,用起来!

四、参考文章

https://developer.android.google.cn/jetpack/androidx/releases/viewpager2?hl=en

https://developer.android.google.cn/training/animation/vp2-migration?hl=zh_cn

https://developer.android.google.cn/training/animation/screen-slide-2?hl=zh_cn

本文地址:https://blog.csdn.net/sinat_35241409/article/details/107536514