ViewPager 和 ViewPager2 都是 Android 中用于实现滑动页面切换的控件,但 ViewPager2
是对 ViewPager
的改进和增强版本。
区别
实现方式
ViewPager
继承自ViewGroup
,内部并未使用已有的成熟控件,更多的是自定义的操作。ViewPager2
也继承自ViewGroup
,但其内部基于RecyclerView
实现,这意味着性能的提升,因为ViewHolder
减少了内存开销,同时RecyclerView
相关方法在ViewPager2
中也可以看到类似封装 。
滑动方向
ViewPager2
支持垂直和水平方向滑动,而ViewPager
仅支持水平方向滑动 。
上面提到其内部基于
RecyclerView
实现,那么我们需要使其垂直滑动只需要在布局文件里面添加一句话android:orientation="vertical"
Adapter(适配器)
ViewPager
使用PagerAdapter
、FragmentPagerAdapter
、FragmentStatePagerAdapter
作为其适配器。
- PagerAdapter:
PagerAdapter
是最基本的适配器,用于管理非Fragment
的页面。- 它提供了
instantiateItem(ViewGroup container, int position)
和destroyItem(ViewGroup container, int position, Object object)
方法来控制页面的创建和销毁。 PagerAdapter
需要手动管理页面的缓存和复用,这可能会导致内存泄漏,如果页面中的资源没有正确释放。
- FragmentPagerAdapter:
FragmentPagerAdapter
是PagerAdapter
的子类,专为Fragment
设计。- 它管理一个
Fragment
的集合,每个Fragment
代表一个页面。 FragmentPagerAdapter
会缓存所有的Fragment
实例,即使它们没有显示在屏幕上。这意味着即使用户导航离开了某个页面,该页面的Fragment
仍然存在,这有助于保持状态,但也可能增加内存使用。
- FragmentStatePagerAdapter:
FragmentStatePagerAdapter
也是PagerAdapter
的子类,同样用于Fragment
。- 与
FragmentPagerAdapter
不同的是,FragmentStatePagerAdapter
只会保留当前页面和直接相邻页面的Fragment
实例。当页面不可见时,它的Fragment
会被销毁,只保留必要的信息以恢复该页面。 - 这种适配器适用于页面数量较多的情况,或者当页面状态不重要时,可以帮助减少内存使用。
ViewPager2
使用RecyclerView.Adapter
,并且对于Fragment
,使用FragmentStateAdapter
作为其适配器 。
懒加载
ViewPager
默认执行预加载,如果需要懒加载的话,需要自行封装。ViewPager2
默认执行懒加载,但是依旧可以设置预加载 。
ViewPager2使用示例
public class MyFragmentTitleAdapter extends FragmentStateAdapter {
private List<Fragment> mfragmentList;
public MyFragmentTitleAdapter(@NonNull FragmentActivity fragmentActivity, List<Fragment> fragments) {
super(fragmentActivity);
this.mfragmentList = fragments;
}
@NonNull
@Override
public Fragment createFragment(int position) {
return mfragmentList == null ? null : mfragmentList.get(position);
}
@Override
public int getItemCount() {
return mfragmentList.size();
}
}
createFragment(int position)
:- 这个方法是根据位置
position
创建一个Fragment
实例。这是实现页面滑动功能的关键方法,你需要在这里返回对应位置的Fragment
。
- 这个方法是根据位置
getItemCount()
:- 这个方法返回
ViewPager2
中页面的总数。这个数字应该等于你想要在ViewPager2
中显示的Fragment
的数量。
- 这个方法返回
public MyFragmentTitleAdapter()
:- 构造适配器的方法
接下来我们只需要在活动当中获取ViewPager2
,并对其创建适配器将其设置进去即可,你就可以看到与相册一样左右滑动切换Fragment,当我们把布局文件设置为垂直滑动图片就会与抖音一样垂直滑动的效果。
上面实现了ViewPager
与TabLayout
的绑定,对于ViewPager2
写法不同,ViewPager2
与 TabLayout
的集成更加简化,通过 TabLayoutMediator
类来实现。TabLayoutMediator
负责在 ViewPager2
和 TabLayout
之间建立联系,自动处理页面变化和 tab 选中状态的同步。
TabLayoutMediator
还支持动态更改标签的数量、内容和样式。
实例:
mviewPager = view.findViewById(R.id.home_vp);
mtabLayout = view.findViewById(R.id.table_layout);
initData(); //初始化碎片集合
myFragmentTitleAdapter = new MyFragmentTitleAdapter(getActivity(), mfragmentList);
mviewPager.setAdapter(myFragmentTitleAdapter);
new TabLayoutMediator(mtabLayout, mviewPager, new TabLayoutMediator.TabConfigurationStrategy() {
@Override
public void onConfigureTab(@NonNull TabLayout.Tab tab, int i) {
tab.setText("Tab" + (i + 1));
}
}).attach();
TabLayoutMediator.TabConfigurationStrategy
:这是一个回调接口,用于配置每个Tab
的内容。在这个例子中,它被用来设置每个标签的文本。onConfigureTab(TabLayout.Tab tab, int i)
:这是TabConfigurationStrategy
接口的实现方法。对于ViewPager2
中的每个页面,这个方法都会被调用一次,以便配置对应的Tab
。@NonNull TabLayout.Tab tab
:这是当前需要配置的Tab
对象。int i
:这是当前Tab
的位置索引,从 0 开始。
tab.setText("Tab" + (i + 1))
:这行代码设置了每个Tab
的文本。).attach()
:这是TabLayoutMediator
的构造函数的结束,attach()
方法用于将中介与TabLayout
和ViewPager2
绑定,并激活这个绑定关系。在调用attach()
之后,TabLayoutMediator
将开始监听ViewPager2
的页面变化,并自动更新TabLayout
中的标签状态。
此时页面就与上面的TabLayout绑定了。
文章到这里就结束了!