一、什么是ViewPager2
ViewPager2 是 Android Jetpack 中的一个组件,用于在屏幕上实现可水平或垂直滑动的页面切换效果。它是早期 ViewPager
库的现代化替代品,解决了 ViewPager
的许多遗留问题并引入了强大的新功能。
你可以把它想象成一个可以左右(或上下)滑动的“相册”或者“引导页”,每一页都是一个独立的视图(Fragment
或 View
),用户通过滑动手势在不同页面间切换。最常见的应用场景包括:
应用引导页:新用户安装应用后的功能介绍幻灯片。
图片浏览器/相册:全屏查看图片,滑动切换上一张/下一张。
标签页:与
TabLayout
结合使用,实现类似 Chrome 浏览器顶部的标签页效果。- 新闻/文章详情流:滑动切换到下一篇新闻或文章。
相较于ViewPager的优点:
- 垂直方向支持
除了支持传统的水平分页
之外,ViewPager2 还支持垂直分页。
您可以通过设置 ViewPager2 元素的android:orientation 属性
为其启用垂直分页:
<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 分页:
<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.添加依赖
dependencies {
implementation "androidx.viewpager2:viewpager2:1.0.0"
}
2.在布局文件中添加ViewPager2
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewPager2"
android:layout_width="match_parent"
android:layout_height="match_parent" />
3.创建要添加的Fragment及其布局文件
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 实例。
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()中设置。
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);
}
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;
}
}