Android 入门到实战(三):ViewPager及ViewPager2多页面布局
一. 引言
在 Android 应用开发中,实现多页面的左右滑动切换,是非常常见且实用的交互方式。ViewPager 组件正是为此而生,帮助我们轻松管理和切换多个页面内容。
不过,随着 Android Jetpack 的发展,Google 推出了 ViewPager 的升级版本 —— ViewPager2,它在功能和性能上都有显著提升,成为了新的官方推荐组件。
本篇文章将带你快速了解旧版 ViewPager 的基本情况及它的两种常用适配器(FragmentPagerAdapter 和 FragmentStatePagerAdapter)之间的区别,随后重点介绍 ViewPager2 的使用方法,并演示如何配合 TabLayout 实现漂亮的滑动标签页效果。通过一个简单的 Activity + 3 个 Fragment 示例,帮助你快速掌握多页面滑动切换的核心技巧。
无论你是刚接触 ViewPager 相关组件,还是想了解 ViewPager2 的实战用法,这篇内容都会为你提供清晰且实用的指导。
二. 旧版 ViewPager 简介及适配器区别
2.1 什么是 ViewPager?
ViewPager 是 Android Support Library(现为 AndroidX)中提供的一个经典组件,用于在多个页面之间实现左右滑动切换。它内部管理多个页面视图,支持手势滑动、页面切换动画以及预加载等功能,使得多页面导航体验更加流畅自然。
2.2 FragmentPagerAdapter 和 FragmentStatePagerAdapter 的区别
在使用 ViewPager 管理 Fragment 页面时,通常会用到两种适配器:
FragmentPagerAdapter
- 适用于页面数量较少且固定的情况。
- 它会保留所有 Fragment 的实例,页面切换时仅隐藏或显示。
- 因为会一直持有所有 Fragment,占用更多内存,适合 Tab 页数较少的场景。
FragmentStatePagerAdapter
- 适用于页面较多或者动态变化的情况。
- 它会在 Fragment 不可见时销毁其视图和状态,仅保存必要的状态信息。
- 能有效节省内存,适合需要管理大量页面的情况。
2.3 代码示例(简要)
class MyPagerAdapter(fm: FragmentManager) : FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {override fun getCount() = 3override fun getItem(position: Int): Fragment {return when(position) {0 -> FragmentA()1 -> FragmentB()else -> FragmentC()}}
}
如果用 FragmentStatePagerAdapter,写法类似,只是继承不同。
2.4 为什么推荐使用 ViewPager2?
尽管旧版 ViewPager 仍在一些项目中使用,但它存在一些设计和性能上的限制,比如:
- 只能水平方向滑动(ViewPager2 支持垂直滑动)
- 不支持 RecyclerView 的所有优势(ViewPager2 基于 RecyclerView 实现)
- 适配现代架构组件支持较弱
因此,Google 推荐在新项目中使用功能更强、灵活性更高的 ViewPager2。
三. ViewPager2 介绍
3.1 ViewPager2 是什么?
ViewPager2 是 Google 推出的 ViewPager 升级版,基于 RecyclerView 实现,拥有更强的功能和更好的性能,同时完美支持 AndroidX 和 Jetpack 架构组件。它的 API 设计更灵活,兼容性更好,是当前新项目的首选。
3.2 相比旧版的主要改进
特性 | ViewPager | ViewPager2 |
---|---|---|
滑动方向 | 仅支持水平方向 | 支持水平 & 垂直 |
底层实现 | 自定义 Layout | 基于 RecyclerView |
数据更新 | 需调用 notifyDataSetChanged(),机制复杂 | 直接使用 RecyclerView Adapter 更新机制 |
生命周期 | 与 Fragment 生命周期适配不够好 | 完全兼容 Fragment Lifecycle & LiveData |
反向布局 | 不支持 | 支持(RTL,倒序显示等) |
3.3 基本使用方式
ViewPager2 继承自 ViewGroup,与 RecyclerView 的 Adapter 配合使用,官方推荐配合 FragmentStateAdapter 来管理 Fragment 页面。它的使用步骤通常为:
- 在布局文件中添加 ViewPager2
- 创建一个继承自 FragmentStateAdapter 的适配器
- 在 Activity/Fragment 中将适配器绑定到 ViewPager2
- (可选)与 TabLayout 结合,使用 TabLayoutMediator 进行绑定
四. ViewPager2 + TabLayout 实现滑动 Tab 布局
下面我们用一个简单的 Activity + 3 个 Fragment,演示如何用 ViewPager2 配合 TabLayout 实现滑动标签页效果。
4.1 activity布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:id="@+id/main"><!-- TabLayout --><com.google.android.material.tabs.TabLayoutandroid:id="@+id/tabLayout"android:layout_width="match_parent"android:layout_height="wrap_content"app:tabIndicatorColor="@android:color/holo_blue_dark"app:tabSelectedTextColor="@android:color/holo_blue_dark"app:tabTextColor="@android:color/darker_gray" /><!-- ViewPager2 --><androidx.viewpager2.widget.ViewPager2android:id="@+id/viewPager2"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1" /></LinearLayout>
4.2 Fragment 布局
以fragment_home.xml为例:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"xmlns:tools="http://schemas.android.com/tools"android:gravity="center"tools:context=".page.MineFragment"><TextViewandroid:id="@+id/tvTitle"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="首页"android:layout_gravity="center"android:textSize="24sp" /></FrameLayout>
4.3 Fragment 类
事实上这都是工具为我们自动创建的以HomeFragment.kt为例:
class HomeFragment : Fragment() {// TODO: Rename and change types of parametersprivate var param1: String? = nullprivate var param2: String? = nulloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)arguments?.let {param1 = it.getString(ARG_PARAM1)param2 = it.getString(ARG_PARAM2)}}override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? {// Inflate the layout for this fragmentreturn inflater.inflate(R.layout.fragment_home, container, false)}companion object {/*** Use this factory method to create a new instance of* this fragment using the provided parameters.** @param param1 Parameter 1.* @param param2 Parameter 2.* @return A new instance of fragment HomeFragment.*/// TODO: Rename and change types and number of parameters@JvmStaticfun newInstance(param1: String, param2: String) =HomeFragment().apply {arguments = Bundle().apply {putString(ARG_PARAM1, param1)putString(ARG_PARAM2, param2)}}}
}
4.4 适配器
MainPagerAdapter.kt
package com.example.viewpagerexample.mainimport androidx.fragment.app.FragmentActivity
import androidx.viewpager2.adapter.FragmentStateAdapter
import com.example.viewpagerexample.page.DiscoverFragment
import com.example.viewpagerexample.page.HomeFragment
import com.example.viewpagerexample.page.MineFragmentclass MainPagerAdapter(activity: FragmentActivity): FragmentStateAdapter(activity) {private val fragments = listOf(HomeFragment(),DiscoverFragment(),MineFragment())override fun getItemCount() = fragments.sizeoverride fun createFragment(position: Int) = fragments[position]
}
4.5 Activity 绑定逻辑
MainActivity.kt
/// 配置tabprivate fun setupTabLayout() {val viewPager = findViewById<androidx.viewpager2.widget.ViewPager2>(R.id.viewPager2)val tabLayout = findViewById<com.google.android.material.tabs.TabLayout>(R.id.tabLayout)// 设置ViewPager2的适配器viewPager.adapter = MainPagerAdapter(this)// 使用 TabLayoutMediator 来绑定val titles = listOf("首页", "发现", "我的")TabLayoutMediator(tabLayout, viewPager) { tab, position ->tab.text = titles[position]}.attach()}
效果如下:
五. 结语
在 Android 界面开发中,ViewPager2 搭配 TabLayout 是一种高效、直观的多页面切换方案。通过 FragmentStateAdapter,我们可以方便地将多个 Fragment 绑定到滑动视图中,而 TabLayoutMediator 则免去了手动同步标签与页面状态的繁琐逻辑,让交互更加顺畅自然。
相比旧版 ViewPager,ViewPager2 在性能、可扩展性、布局灵活性等方面都有显著提升,支持垂直滑动、RTL 布局、RecyclerView 优化等特性。对于新项目而言,已经没有理由再去使用旧的 ViewPager 与 FragmentPagerAdapter。
至此,我们通过一个 单 Activity + 多 Fragment + TabLayout + ViewPager2 的实战案例,完成了从基本使用到交互优化的全过程。掌握了这一套模式,你就可以轻松实现首页导航、功能分类、内容切换等多种常见 UI 场景,为应用提供更优的用户体验。