ViewPager2 系列-- 初探ViewPager2

ViewPager2是什么

ViewPager2是Android Jetpack库中的一个组件,是用于在应用程序中实现页面切换和滑动效果的容器。

ViewPager2的作用和用途

ViewPager2是一个功能强大的滑动容器,可以应用于多种场景中,提供了灵活的页面切换和布局定制功能,使得应用程序界面更加丰富和交互性强,可以用于以下场景:

  1. 实现引导页或欢迎页:ViewPager2可以用于创建引导页或欢迎页,让用户通过滑动浏览介绍应用程序功能或展示欢迎内容。

  2. 创建图片浏览器:ViewPager2可以用于创建图片浏览器,允许用户通过滑动来切换不同的图片,并支持缩放和手势交互。

  3. 构建轮播图:ViewPager2非常适合构建轮播图功能,可以通过适配器动态加载不同的轮播项,并提供自动循环滚动的功能。

  4. 实现选项卡式布局:结合TabLayout,ViewPager2可以用于创建选项卡式布局,让用户通过滑动选项卡来切换不同的内容页面。

  5. 创建垂直滑动页面:与ViewPager不同,ViewPager2支持垂直方向的滑动,因此可以用于创建垂直滑动的页面布局,例如垂直滑动的导航菜单或垂直的新闻列表。

  6. 实现分页数据展示:ViewPager2可以用于展示分页数据,例如将大量数据按页加载并在每一页中展示一部分内容。

  7. 嵌套滑动布局:ViewPager2可以与其他滑动组件(如RecyclerView)嵌套使用,实现复杂的滑动布局结构。

  8. 实现自定义的滑动效果:通过使用自定义的转换器(Transformer),可以实现各种炫酷的页面切换效果,例如渐变、缩放、旋转等。

ViewPager2相较于ViewPager的改进和优势

ViewPager2是对ViewPager的改进版本,提供了更好的性能、更灵活的适配器和更丰富的功能。它是构建滑动页面布局的首选组件,可以在应用程序中实现各种滑动页面的需求,并提供更好的用户体验,大致有以下几点改进和优势:

  1. 支持垂直滑动:ViewPager2是在ViewPager的基础上进行改进的,最显著的改进之一是支持垂直滑动。而在ViewPager中,只支持水平滑动。这使得ViewPager2在创建垂直布局或特定场景下的垂直滑动功能更加方便和灵活。

  2. 更好的性能和稳定性:ViewPager2内部实现使用了RecyclerView作为容器,而不再依赖于ViewPager的实现方式。这使得ViewPager2具有RecyclerView的优势,例如更好的性能和内存管理、更流畅的滑动体验以及更好的布局回收和复用机制。同时,ViewPager2还解决了ViewPager一些已知的问题和不稳定性,如条目位置错乱、刷新数据的不及时等。

  3. 支持使用Fragment作为页面:与ViewPager不同,ViewPager2直接支持使用Fragment作为页面,而无需通过FragmentPagerAdapter或FragmentStatePagerAdapter进行适配。这简化了页面管理和生命周期处理,并提供了更直观和一致的使用体验。

  4. 更灵活的适配器:ViewPager2引入了新的适配器接口,即RecyclerView.Adapter的子类RecyclerView.Adapter。这使得适配器的创建和管理更加灵活,同时提供了更多的功能和扩展性。

  5. 更丰富的功能和接口:ViewPager2提供了许多新的功能和接口,例如支持页面预加载、更强大的页面切换动画支持、更丰富的回调接口等。这些功能和接口使得开发者能够更好地控制和定制ViewPager2的行为和外观。

环境配置和依赖

  1. 在你的项目模块的build.gradle文件中,添加以下依赖项:
dependencies {
    // ...
    implementation 'androidx.viewpager2:viewpager2:1.0.0'
}

  1. 确保你的项目使用了AndroidX,可以在gradle.properties文件中添加以下配置:
arduinoCopy code
android.useAndroidX=true
android.enableJetifier=true

ViewPager2基本用法

  • 创建一个包含ViewPager2的布局文件

  • 在Activity或Fragment中查找和实例化ViewPager2

  • 创建和设置适配器(Adapter)来管理ViewPager2的内容

  • 设置适配器到ViewPager2实例

与View结合使用

以下是使用Kotlin的ViewPager2基本用法示例:

  1. 在XML布局文件中定义ViewPager2:
<androidx.viewpager2.widget.ViewPager2
    android:id="@+id/viewPager"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

  1. 在Activity或Fragment中,获取ViewPager2实例并设置适配器:
val viewPager: ViewPager2 = findViewById(R.id.viewPager)
val adapter = MyAdapter() // 自定义适配器,需要继承RecyclerView.Adapter
viewPager.adapter = adapter

  1. 创建自定义适配器MyAdapter,继承自RecyclerView.Adapter
class MyAdapter : RecyclerView.Adapter<MyViewHolder>() {

    // 在这里定义你的数据源
    private val dataList: MutableList<String> = mutableListOf()

    // 添加数据到数据源
    fun setData(data: List<String>) {
        dataList.clear()
        dataList.addAll(data)
        notifyDataSetChanged()
    }

    // 创建ViewHolder
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.item_view, parent, false)
        return MyViewHolder(view)
    }

    // 绑定数据到ViewHolder
    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        val data = dataList[position]
        holder.bindData(data)
    }

    // 返回数据源的大小
    override fun getItemCount(): Int {
        return dataList.size
    }
}

  1. 创建ViewHolder类MyViewHolder,继承自RecyclerView.ViewHolder
class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

    private val textView: TextView = itemView.findViewById(R.id.textView)

    fun bindData(data: String) {
        textView.text = data
    }
}

  1. item_view.xml布局文件中定义每个页面的布局,例如一个简单的TextView:
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/itemLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
    android:id="@+id/textView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textSize="16sp"
    android:padding="16dp" />

</LinearLayout>

注意:布局文件的根视图的宽度和高度设置为match_parent ,否则会报错:

java.lang.IllegalStateException: Pages must fill the whole ViewPager2 (use match_parent)

通过上述步骤,就可以在ViewPager2中显示自定义的页面,并通过适配器来管理数据源和页面布局。

与Fragment结合使用

ViewPager2除了配合View使用,更多会和Fragment结合使用,此时我们只需要借助FragmentStateAdapter,简单实现如下:


class MyFragmentStateAdapter(fragmentActivity: FragmentActivity) : FragmentStateAdapter(fragmentActivity) {

    private val fragmentList = listOf(
        FirstFragment(),
        SecondFragment(),
        ThirdFragment()
    )

    override fun getItemCount(): Int {
        return fragmentList.size
    }

    override fun createFragment(position: Int): Fragment {
        return fragmentList[position]
    }
}

然后,在MainActivity中使用ViewPager2和适配器:


class MainActivity : AppCompatActivity() {

    private lateinit var viewPager: ViewPager2

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        viewPager = findViewById(R.id.viewPager)
        val adapter = MyFragmentStateAdapter(this)
        viewPager.adapter = adapter
    }
}

如何监听页面切换事件

要监听页面切换事件,你可以在 ViewPager2 上设置一个 OnPageChangeCallback 对象来监听页面的变化。OnPageChangeCallback 提供了几个方法,可以在页面被选中、滚动和滚动状态改变时触发相应的回调。

下面是一个示例,展示了如何监听页面切换事件:

import androidx.appcompat.app.AppCompatActivity
import androidx.viewpager2.widget.ViewPager2
import androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback

class MainActivity : AppCompatActivity() {

    private lateinit var viewPager: ViewPager2

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        viewPager = findViewById(R.id.viewPager)

        // 设置页面切换监听
        viewPager.registerOnPageChangeCallback(object : OnPageChangeCallback() {
            override fun onPageSelected(position: Int) {
                // 当页面选中时触发回调
                // 在这里可以根据需要执行相应的操作
            }

            override fun onPageScrolled(
                position: Int,
                positionOffset: Float,
                positionOffsetPixels: Int
            ) {
                // 当页面滚动时触发回调
                // 在这里可以根据需要执行相应的操作
            }

            override fun onPageScrollStateChanged(state: Int) {
                // 当页面滚动状态改变时触发回调
                // 在这里可以根据需要执行相应的操作
            }
        })
    }
}

页面滚动状态都有哪些

ViewPager2 的页面滚动状态有三种,分别对应不同的整数值:

  1. ViewPager2.SCROLL_STATE_IDLE(值为 0):空闲状态。表示当前页面处于静止状态,没有正在进行的滚动操作。

  2. ViewPager2.SCROLL_STATE_DRAGGING(值为 1):拖动状态。表示用户正在拖动页面,准备进行滚动操作。

  3. ViewPager2.SCROLL_STATE_SETTLING(值为 2):滚动状态。表示页面正在自动滚动到最终的位置。

可以通过 ViewPager2.OnPageChangeCallbackonPageScrollStateChanged() 方法中的 state 参数获取当前的页面滚动状态。根据不同的状态值,可以执行相应的操作,例如显示加载指示器、更新界面等。

自定义动画切换动画和过渡效果

要自定义页面切换动画和过渡效果,我们可以使用 ViewPager2.PageTransformer 接口来实现。PageTransformer 允许在页面切换时对页面应用自定义的动画和过渡效果。

下面是一个示例,展示了如何自定义页面切换动画和过渡效果:

import android.view.View
import androidx.viewpager2.widget.ViewPager2

class CustomPageTransformer : ViewPager2.PageTransformer {

    override fun transformPage(page: View, position: Float) {
        val absPosition = Math.abs(position)

        // 在这里根据需要对页面进行自定义动画和过渡效果的操作

        // 例如,可以对页面进行缩放和透明度变化
        page.scaleY = 0.85f + (1f - 0.85f) * (1f - absPosition)
        page.alpha = 0.5f + (1f - 0.5f) * (1f - absPosition)
    }
}

在上述示例中,我们创建了一个名为 CustomPageTransformer 的类,并实现了 ViewPager2.PageTransformer 接口。在 transformPage() 方法中,我们可以根据需要对每个页面进行自定义的动画和过渡效果。

在这个示例中,我们对页面进行了简单的缩放和透明度变化。根据页面的位置(position),我们设置了不同的缩放和透明度值。

接下来,将 CustomPageTransformer 应用到 ViewPager2 上:

val viewPager: ViewPager2 = findViewById(R.id.viewPager)
val adapter = MyAdapter()
viewPager.adapter = adapter

val pageTransformer = CustomPageTransformer()
viewPager.setPageTransformer(pageTransformer)

在这个示例中,我们首先实例化了 ViewPager2 和适配器 MyAdapter。然后,我们创建了 CustomPageTransformer 的实例,并通过 setPageTransformer() 方法将其应用到 ViewPager2 上。

如何禁用或限制页面切换

要禁用或限制页面切换,可以使用 ViewPager2.OnPageChangeCallback 监听器来控制页面切换的行为。通过在回调方法中处理逻辑,你可以决定是否允许页面切换。

下面是一个示例,展示了如何禁用或限制页面切换:

import androidx.viewpager2.widget.ViewPager2

class CustomOnPageChangeCallback : ViewPager2.OnPageChangeCallback() {

    private var isPageChangeEnabled = true

    fun setPageChangeEnabled(enabled: Boolean) {
        isPageChangeEnabled = enabled
    }

    override fun onPageSelected(position: Int) {
        if (!isPageChangeEnabled) {
            // 如果页面切换被禁用,则强制将选中的页面切换回原始位置
            // 这样可以避免用户手动滑动页面
            val viewPager = /* 获取 ViewPager2 实例 */
            viewPager.setCurrentItem(/* 原始位置 */, false)
        }
    }

    override fun onPageScrollStateChanged(state: Int) {
        if (!isPageChangeEnabled && state == ViewPager2.SCROLL_STATE_DRAGGING) {
            // 如果页面切换被禁用,并且用户尝试拖动页面,
            // 则强制将滚动状态设置为 SCROLL_STATE_IDLE,防止页面滚动
            val viewPager = /* 获取 ViewPager2 实例 */
            viewPager.scrollToPosition(/* 原始位置 */)
        }
    }
}

在上述示例中,我们创建了一个名为 CustomOnPageChangeCallback 的类,继承自 ViewPager2.OnPageChangeCallback。我们添加了一个 setPageChangeEnabled() 方法,用于启用或禁用页面切换。

onPageSelected() 方法中,我们检查 isPageChangeEnabled 的状态。如果页面切换被禁用,我们使用 ViewPager2 实例将选中的页面切换回原始位置,这样可以防止用户手动滑动页面。

onPageScrollStateChanged() 方法中,我们检查 isPageChangeEnabled 的状态以及滚动状态。如果页面切换被禁用,并且用户尝试拖动页面,我们强制将滚动状态设置为 SCROLL_STATE_IDLE,这样可以防止页面滚动。

然后,将 CustomOnPageChangeCallback 应用到 ViewPager2 上:

val viewPager: ViewPager2 = findViewById(R.id.viewPager)
val adapter = MyAdapter()
viewPager.adapter = adapter

val onPageChangeCallback = CustomOnPageChangeCallback()
viewPager.registerOnPageChangeCallback(onPageChangeCallback)

在这个示例中,我们首先实例化了 ViewPager2 和适配器 MyAdapter。然后,我们创建了 CustomOnPageChangeCallback 的实例,并通过 registerOnPageChangeCallback() 方法将其注册到 ViewPager2 上。

要禁用或启用页面切换,只需调用 setPageChangeEnabled() 方法并传递相应的参数即可:

onPageChangeCallback.setPageChangeEnabled(false) // 禁用页面切换
onPageChangeCallback.setPageChangeEnabled(true)

滑动方向设置

要设置 ViewPager2 的滑动方向,你可以通过设置 Orientation 属性来实现。ViewPager2 支持两种滑动方向:水平滑动和垂直滑动。

在布局文件中,将 ViewPager2android:orientation 属性设置为 horizontal(水平滑动)或 vertical(垂直滑动)即可。

<androidx.viewpager2.widget.ViewPager2
    android:id="@+id/viewPager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" />

在上述示例中,我们将 ViewPager2android:orientation 属性设置为 "horizontal",以实现水平滑动。如果你想实现垂直滑动,只需将属性值设置为 "vertical"

页面预加载

要设置 ViewPager2 的页面预加载数量,你可以使用 setOffscreenPageLimit() 方法。setOffscreenPageLimit() 方法用于设置 ViewPager2 在当前页面附近预加载的页面数量。

默认情况下,ViewPager2 的页面预加载数量为 1,即当前页面的左右各一个页面会被预加载。你可以根据需要增加或减少预加载的页面数量。

以下是示例代码,展示了如何设置 ViewPager2 的页面预加载数量为 2:

val viewPager: ViewPager2 = findViewById(R.id.viewPager)
viewPager.offscreenPageLimit = 2

在上述示例中,我们通过 viewPager.offscreenPageLimit 属性将页面预加载数量设置为 2。这意味着在当前页面的左右各两个页面会被预加载。

最后

如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
在这里插入图片描述
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。

全套视频资料:

一、面试合集

在这里插入图片描述
二、源码解析合集
在这里插入图片描述

三、开源框架合集
在这里插入图片描述
欢迎大家一键三连支持,若需要文中资料,直接扫描文末CSDN官方认证微信卡片免费领取↓↓↓

PS:群里还设有ChatGPT机器人,可以解答大家在工作上或者是技术上的问题

你可能感兴趣的:(android,android,jetpack)