ViewPager2介绍
ViewPager2
是 Android Jetpack 组件的一部分,旨在取代老旧的 ViewPager
。它主要用于在多个页面之间滑动切换,适合展示分屏内容,如教程引导页、图片浏览器等。
与 ViewPager
不同,ViewPager2
使用了 RecyclerView
作为底层技术,因此拥有更灵活的功能和更好的性能。ViewPager2
支持横向和纵向滑动、Fragment 的更高效管理。
基础使用
-
布局文件添加ViewPage2
<androidx.viewpager2.widget.ViewPager2 android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="match_parent" />
-
设置适配器
ViewPager2
使用RecyclerView.Adapter
作为其适配器。你可以像使用RecyclerView
一样,创建一个Adapter
来填充ViewPager2
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private List<String> dataList;
public MyAdapter(List<String> dataList) {
this.dataList = dataList;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.page_item, parent, false);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
holder.textView.setText(dataList.get(position));
}
@Override
public int getItemCount() {
return dataList.size();
}
static class MyViewHolder extends RecyclerView.ViewHolder {
TextView textView;
MyViewHolder(View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.textView);
}
}
}
-
view绑定适配器
ViewPager2 viewPager = findViewById(R.id.viewPager); List<String> data = Arrays.asList("Page 1", "Page 2", "Page 3"); MyAdapter adapter = new MyAdapter(data); viewPager.setAdapter(adapter);
[!NOTE]
item布局文件的宽度和高度要设置为match_parent,否则会报错:java.lang.IllegalStateException: Pages must fill the whole ViewPager2 (use match_parent)
扩展使用
滑动方向
ViewPager2默认滑动方向为横向,也可通过代码修改为垂直滑动
viewPager.setOrientation(ViewPager2.ORIENTATION_VERTICAL);
搭配Fragment
ViewPager2
允许使用 Fragment
作为页面的一部分。可以通过 FragmentStateAdapter
来实现这一点,它是 ViewPager2
提供的适配器之一:
public class MyFragmentAdapter extends FragmentStateAdapter {
private List<Fragment> fragmentList;
public MyFragmentAdapter(@NonNull FragmentActivity fragmentActivity, List<Fragment> fragmentList) {
super(fragmentActivity);
this.fragmentList = fragmentList;
}
@NonNull
@Override
public Fragment createFragment(int position) {
return fragmentList.get(position);
}
@Override
public int getItemCount() {
return fragmentList.size();
}
}
使用适配器需要传入一个fragment的列表
ViewPager2 viewPager = findViewById(R.id.viewPager);
List<Fragment> fragments = Arrays.asList(new Fragment1(), new Fragment2(), new Fragment3());
MyFragmentAdapter adapter = new MyFragmentAdapter(this, fragments);
viewPager.setAdapter(adapter);
修改页面切换动画
ViewPager2
支持自定义页面转换动画,可以使用 PageTransformer
来创建自定义的动画效果,transformPage
有page和position两个参数,page是正在处理的页面视图,position是滑动的距离,这个值是一个浮点值,当页面在屏幕中央时,position为0,当页面左滑时,值为慢慢变小,当页面完全离开屏幕时,position为-1,右滑的话值会慢慢变大,完全离开屏幕时,position为1,通过position的值,我们可以对page进行设置页面切换效果。
viewPager2.setPageTransformer(new ViewPager2.PageTransformer() {
@Override
public void transformPage(@NonNull View page, float position) {
}
});
page的一些操作
1.setAlpha(float alpha),设置页面的透明度
page.setAlpha(0.5f); // 将页面设置为半透明
2.setTranslationX(float translationX),设置页面x轴的位移,水平位移
page.setTranslationX(page.getWidth() * position); // 根据滑动位置移动页面
3.setTranslationY(float translationY),设置页面y轴的位移,垂直位移
page.setTranslationY(page.getHeight() * position); // 根据滑动位置上下移动页面
4.setTranslationZ(float translationZ),设置页面z轴的位移
// 将视图向前移动 10 个像素,靠近用户
page.setTranslationZ(10f);
// 将视图向后移动 5 个像素,远离用户
page.setTranslationZ(-5f);
5.setScaleX(float scaleX),设置页面的水平缩放比例
page.setScaleX(0.8f); // 将页面的宽度缩小到80%
6.setScaleY(float scaleY),设置页面的垂直缩放比例
page.setScaleY(0.8f); // 将页面的高度缩小到80%
7.setRotation(float rotation),设置页面的旋转角度
page.setRotation(30 * position); // 根据位置旋转页面
8.setRotationX(float rotationX),设置页面绕 X轴的旋转角度。
page.setRotationX(30 * position); // 页面绕X轴旋转
9.setRotationY(float rotationY),设置页面绕 Y轴的旋转角度。
page.setRotationY(30 * position); // 页面绕Y轴旋转
10.setPivotX(float pivotX),设置页面的水平旋转轴位置。
page.setPivotX(page.getWidth() * 0.5f); // 旋转轴位于页面中心
11.setPivotY(float pivotY),设置页面的垂直旋转轴位置。
page.setPivotY(page.getHeight() * 0.5f); // 旋转轴位于页面中心
12.setVisibility(int visibility),设置页面的可见性。
page.setVisibility(View.INVISIBLE); // 将页面设置为不可见但保留空间
- 说明: 可以使用
View.VISIBLE
,View.INVISIBLE
,View.GONE
三种值。
13.setBackgroundColor(int color),设置页面的背景颜色。
page.setBackgroundColor(Color.RED); // 将页面背景设置为红色
14.animate(),提供动画 API 来组合多个动画。
page.animate().alpha(0.5f).translationX(100).setDuration(300).start(); // 动画改变透明度和位置
切换效果的一些事例
淡入淡出
page.setAlpha(1 - Math.abs(position));
page.setTranslationX(page.getWidth() * -position);
[!NOTE]
由于被划出的页面绝对值会越来越大,所以透明度会越来越淡,直到完全透明。
而滑入的页面绝对值会越来越小,页面会越来越不透明
扇子切换效果
// 设置页面的旋转中心
page.setPivotX(0);
page.setPivotY(page.getHeight());
// 根据 position 设置旋转角度
float rotation = 60f * position;
page.setRotation(rotation);
仿书籍翻页效果
将所有在画面右侧的view叠在一起,每次左滑,都会把第一个view滑走,第二个view抬起
参考https://blog.csdn.net/weixin_44370506/article/details/127161098?spm=1001.2014.3001.5502
if (position>=0){
page.setTranslationX((-page.getWidth() * position));
page.setTranslationZ(-position);
}
页面监听
ViewPager2
提供了 OnPageChangeCallback
接口,可以监听页面滑动、页面选中、页面滚动状态的变化
viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
super.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
}
@Override
public void onPageScrollStateChanged(int state) {
super.onPageScrollStateChanged(state);
}
});
onPageScrolled(int position, float positionOffset, int positionOffsetPixels),监听页面滑动和切换
position
:当前可见的页面位置,即当前处于视图窗口中的页面索引。这个索引是基于ViewPager2
的适配器(Adapter)中的项。positionOffset
:表示从当前页面滑动到下一个页面的进度百分比,范围是[0, 1)
。当用户完全停止滑动时,值为0
。positionOffsetPixels
:从当前页面滑动到下一个页面的进度,以像素为单位。当用户完全停止滑动时,值为0
。
onPageSelected(int position),当前停留的页面索引
position
:选中的页面位置,表示用户当前停留的页面索引。
onPageScrollStateChanged(int state),监听页面的滑动与开始
state
表示页面滚动的状态。它有三个可能的值:ViewPager2.SCROLL_STATE_IDLE
(0):表示ViewPager2
处于空闲状态,即没有滚动。ViewPager2.SCROLL_STATE_DRAGGING
(1):表示用户正在手指拖动页面,ViewPager2
处于拖动状态。ViewPager2.SCROLL_STATE_SETTLING
(2):表示ViewPager2
处于自动滑动状态,通常是由于用户松开手指后页面自动滑动到新的位置。