ViewPager2最显著的特点是基于RecyclerView实现,RecyclerView是目前Android端最成熟的AdapterView解决方案,这带来诸多好处:
1、抛弃传统的PagerAdapter,统一了Adapter的API/
2、通过LinearLayoutManager可以实现类似抖音的纵向滑动
3、支持DiffUitl,可以通过diff实现局部刷新
4、支持RTL(right-to-left)布局,对于一些有出海需求的APP非常有用
5、支持ItemDecorator
一、ViewPager2和ViewPager的对比:
1、ViewPager2内部实现是RecyclerView,所以ViewPager2的性能更高。
2、ViewPager2可以实现竖向滑动,ViewPager只能横向滑动。
3、ViewPager2只有一个adapter,FragmentStateAdapter继承自RecyclerView.Adapter。
而ViewPager有两个adapter,FragmentStatePagerAdapter和FragmentPagerAdapter,均是继承PagerAdapter。FragmentStatePagerAdapter和FragmentPagerAdapter两者的区别是FragmentStatePagerAdapter不可以缓存,FragmentPagerAdapter可以缓存。
4、ViewPager2模式实现了懒加载,默认不进行预加载。内部是通过Lifecycle 对 Fragment 的生命周期进行管理。ViewPager会进行预加载,懒加载需要我们自己去实现。

效果图:

- public class MainActivity extends AppCompatActivity {
-
- private TabLayout tabLayout;
- private ViewPager2 viewPager2;
-
- private int activeColor = Color.parseColor("#ff678f");
- private int normalColor = Color.parseColor("#666666");
-
- private int activeSize = 20;
- private int normalSize = 14;
-
- private ArrayList
fragments; - private TabLayoutMediator mediator;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- tabLayout = findViewById(R.id.tab_layout);
- viewPager2 = findViewById(R.id.view_pager);
-
- final String[] tabs = new String[]{"关注", "推荐", "最新0", "最新1", "最新2", "最新3", "最新4", "最新5", "最新6"};
-
- //禁用预加载
- viewPager2.setOffscreenPageLimit(ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT);
- //Adapter
- viewPager2.setAdapter(new FragmentStateAdapter(getSupportFragmentManager(), getLifecycle()) {
- @NonNull
- @Override
- public Fragment createFragment(int position) {
- //FragmentStateAdapter内部自己会管理已实例化的fragment对象。
- // 所以不需要考虑复用的问题
- return TestFragment.newInstance(tabs[position]);
- }
-
- @Override
- public int getItemCount() {
- return tabs.length;
- }
- });
- //viewPager 页面切换监听监听
- viewPager2.registerOnPageChangeCallback(changeCallback);
-
- mediator = new TabLayoutMediator(tabLayout, viewPager2, new TabLayoutMediator.TabConfigurationStrategy() {
- @Override
- public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
- //这里可以自定义TabView
- TextView tabView = new TextView(MainActivity.this);
-
- int[][] states = new int[2][];
- states[0] = new int[]{android.R.attr.state_selected};
- states[1] = new int[]{};
-
- int[] colors = new int[]{activeColor, normalColor};
- ColorStateList colorStateList = new ColorStateList(states, colors);
- tabView.setText(tabs[position]);
- tabView.setTextSize(normalSize);
- tabView.setTextColor(colorStateList);
-
- tab.setCustomView(tabView);
- }
- });
- //要执行这一句才是真正将两者绑定起来
- mediator.attach();
- }
-
- private ViewPager2.OnPageChangeCallback changeCallback = new ViewPager2.OnPageChangeCallback() {
- @Override
- public void onPageSelected(int position) {
- //可以来设置选中时tab的大小
- int tabCount = tabLayout.getTabCount();
- for (int i = 0; i < tabCount; i++) {
- TabLayout.Tab tab = tabLayout.getTabAt(i);
- TextView tabView = (TextView) tab.getCustomView();
- if (tab.getPosition() == position) {
- tabView.setTextSize(activeSize);
- tabView.setTypeface(Typeface.DEFAULT_BOLD);
- } else {
- tabView.setTextSize(normalSize);
- tabView.setTypeface(Typeface.DEFAULT);
- }
- }
- }
- };
-
- @Override
- protected void onDestroy() {
- mediator.detach();
- viewPager2.unregisterOnPageChangeCallback(changeCallback);
- super.onDestroy();
- }
- }
- <com.google.android.material.tabs.TabLayout
- android:id="@+id/tab_layout"
- android:layout_width="match_parent"
- android:layout_height="40dp"
- app:tabGravity="center"
- app:tabIndicatorColor="#ff678f"
- app:tabIndicatorFullWidth="false"
- app:tabIndicatorHeight="2dp"
- app:tabMode="scrollable"
- app:tabSelectedTextColor="#ff678f"
- app:tabTextColor="#333333"
- app:tabUnboundedRipple="true" />
-
-
- <androidx.viewpager2.widget.ViewPager2
- android:id="@+id/view_pager"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1"
- android:orientation="horizontal" />
viewPager2可以通过设置android:orientation属性来设置切换方向,支持上下、左右切换。
对应tab页面的实现效果在Fragment中进行实现。
- public class TestFragment extends Fragment {
-
- private View rootView;
-
- public static TestFragment newInstance(String text) {
-
- Bundle args = new Bundle();
- args.putString("text", text);
- TestFragment fragment = new TestFragment();
- fragment.setArguments(args);
- return fragment;
- }
-
- @Nullable
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
- rootView = inflater.inflate(R.layout.fragment_test, container, false);
- return rootView;
- }
-
- @Override
- public void onActivityCreated(@Nullable Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- TextView textView = rootView.findViewById(R.id.text_view);
- String text = getArguments() != null ? getArguments().getString("text") : null;
- textView.setText(text);
- }
- }
几个注意的点!!
看下源码tag怎么设置的,调用链如下:
FragmentStateAdapter-》onBindViewHolder-》placeFragmentInViewHolder方法
- mFragmentManager.beginTransaction()
- .add(fragment, "f" + holder.getItemId())
- .setMaxLifecycle(fragment, STARTED)
- .commitNow();
setOffscreenPageLimit()设置预加载与缓存(1)ViewPager 会预加载几页
(2)ViewPager 会缓存 2*n+1 页(n为设置的值)
如设置为n=1,预加载页数1页,缓存页数3页。如果当前在第一页,会预加载第二页,滑倒第二页,会预加载第三页,当滑倒第三页,第一页会销毁,第四页会加载。