【Android】ViewPager2结合Fragment实现多页面滑动切换

一、什么是ViewPager2

ViewPager2 是 Android Jetpack 中的一个组件,用于在屏幕上实现可水平或垂直滑动的页面切换效果。它是早期 ViewPager 库的现代化替代品,解决了 ViewPager 的许多遗留问题并引入了强大的新功能。

你可以把它想象成一个可以左右(或上下)滑动的"相册"或者"引导页",每一页都是一个独立的视图(FragmentView),用户通过滑动手势在不同页面间切换。最常见的应用场景包括:

  • 应用引导页:新用户安装应用后的功能介绍幻灯片。

  • 图片浏览器/相册:全屏查看图片,滑动切换上一张/下一张。

  • 标签页 :与 TabLayout 结合使用,实现类似 Chrome 浏览器顶部的标签页效果。

  • 新闻/文章详情流:滑动切换到下一篇新闻或文章。

相较于ViewPager的优点:

  • 垂直方向支持
    除了支持传统的水平分页之外,ViewPager2 还支持垂直分页。您可以通过设置 ViewPager2 元素的 android:orientation 属性为其启用垂直分页:
java 复制代码
<androidx.viewpager2.widget.ViewPager2
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/pager"
        android:orientation="vertical" />
    
  • 从右到左支持

ViewPager2 支持从右到左 (RTL) 分页。系统会根据语言区域在适当的情况下自动启用 RTL 分页,不过您也可以通过设置 ViewPager2 元素的 android:layoutDirection 属性为其手动启用 RTL 分页:

java 复制代码
<androidx.viewpager2.widget.ViewPager2
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/pager"
        android:layoutDirection="rtl" />
    
  • 可修改的 Fragment 集合

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

这意味着,您的应用可以在运行时动态修改 Fragment 集合,而 ViewPager2 会正确显示修改后的集合。

二、ViewPager2结合Fragment使用

1.添加依赖

java 复制代码
dependencies {
    implementation "androidx.viewpager2:viewpager2:1.0.0"
}

2.在布局文件中添加ViewPager2

XML 复制代码
<androidx.viewpager2.widget.ViewPager2
    android:id="@+id/viewPager2"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

3.创建要添加的Fragment及其布局文件

java 复制代码
import androidx.fragment.app.Fragment;

public class MainFragment extends Fragment {

    private static final String ARG_ID = "id";

    public static MainFragment newInstance(String id) {
        MainFragment fragment = new MainFragment();
        Bundle args = new Bundle();
        args.putString(ARG_ID, id);
        fragment.setArguments(args);
        return fragment;
    }

    // 完整的 Fragment 实现...
}

在其中编写newInstance方法,方便在Adapter中创建实例。

4.创建适配器

自定义Adapter继承 FragmentStateAdapter,重写getItemCount()和createFragment(position: Int)。

其中,getItemCount()返回 ViewPager2 中总共有多少页(即有多少个 Fragment);

createFragment(position: Int)根据给定的位置(position)创建并返回对应的 Fragment 实例。

java 复制代码
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter;

import java.util.List;

public class DynamicFragmentStateAdapter extends FragmentStateAdapter {

    private final List<Data> dataList;

    public DynamicFragmentStateAdapter(@NonNull FragmentActivity fragmentActivity, List<Data> dataList) {
        super(fragmentActivity);
        this.dataList = dataList;
    }

    public DynamicFragmentStateAdapter(@NonNull Fragment fragment, List<Data> dataList) {
        super(fragment);
        this.dataList = dataList;
    }

    @NonNull
    @Override
    public Fragment createFragment(int position) {
        // 获取当前位置的数据
        Data data = dataList.get(position);
        
       return MainFragment.newInstance(data);
       
    }

    @Override
    public int getItemCount() {
        return dataList != null ? dataList.size() : 0;
    }

    // 可选:更新数据的方法
    public void updateData(List<Data> newDataList) {
        this.dataList.clear();
        this.dataList.addAll(newDataList);
        notifyDataSetChanged(); // 通知适配器数据已更改
    }
}

5.在Activity或Fragment中设置适配器

在Activity的onCreate()中设置,在Fragment的onCreateView()中设置。

java 复制代码
 private ViewPager2 viewPager2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        viewPager2 = findViewById(R.id.view_pager);
        MainFragmentAdapter adapter = new MainFragmentAdapter(this);
        viewPager2.setAdapter(adapter);
    }
java 复制代码
public class ParentFragment extends Fragment {

    private ViewPager2 viewPager2;

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_parent, container, false);
        
        viewPager2 = view.findViewById(R.id.view_pager);
        MainFragmentAdapter adapter = new MainFragmentAdapter(this);
        viewPager2.setAdapter(adapter);
        
        return view;
    }
}
相关推荐
小趴菜82275 分钟前
安卓接入Kwai广告源
android·kotlin
2501_9160137426 分钟前
iOS 混淆与 App Store 审核兼容性 避免被拒的策略与实战流程(iOS 混淆、ipa 加固、上架合规)
android·ios·小程序·https·uni-app·iphone·webview
程序员江同学1 小时前
Kotlin 技术月报 | 2025 年 9 月
android·kotlin
码农的小菜园2 小时前
探究ContentProvider(一)
android
时光少年3 小时前
Compose AnnotatedString实现Html样式解析
android·前端
hnlgzb4 小时前
安卓中,kotlin如何写app界面?
android·开发语言·kotlin
jzlhll1235 小时前
deepseek kotlin flow快生产者和慢消费者解决策略
android·kotlin
火柴就是我5 小时前
Android 事件分发之动态的决定某个View来处理事件
android
一直向钱5 小时前
FileProvider 配置必须针对 Android 7.0+(API 24+)做兼容
android
zh_xuan5 小时前
Android 消息循环机制
android