One, foreword

We have heard that Google is providing us with a new control to replace the old ViewPager and solve some difficult to solve the bug, said a lot of, is the cause of what… Believe readers have been “Zhang Hongyang” great spirit, “Guo Lin” great spirit, or other Android bosses of the public, there to see many, many, perhaps you feel very boring, rookie, the author analyses the background history, also is not very good source code, but the rookie, you can bring a reader tastes fresh, teach you how to do, how to get started, gossip is not much said, We got down to business.

Viewpager has two drawbacks

  1. Preloading cannot be turned off

  2. The adapter update does not take effect

    • When loading data, viewPager preloads the data for the first and second pages by default, and the two views are not visible.
    • Because viewPager limits offscreenPageLimit, the default setting is 1, so page preloading is inevitable. It is also easy to waste resources.
    • Viewpager and Frament are used together, and the fragment setUserVisibleHint method is used to control lazy data loading. Layouts can only be entered in advance (pre-layout).

ViewPager2 off-screen loading and preloading

Preloading ViewPager2 is fundamentally different from off-screen loading at the view level. The off-screen loading view has been added to the parent, whereas preloading prepares the layout, not the parent.

  1. ViewPager2 by default, preloading is enabled and off-screen loading is disabled. It may preload a piece of data, and off-screen loading is set to 0.
  2. ViewPager2 When offscreenPageLimit is set to 1, 2 pieces of data will be loaded on page 1, each slide will load the next page of data, until page 5, the first page of data will be removed.

ViewPager2 ViewPager

  1. The biggest change to the ViewPager2API is that it now uses RecyclerView.
  2. Using ViewPager2 requires migration to Androidx because ViewPager2 is not supported in the Android.support library
  3. FragmentStateAdapter replace FragmentStatePagerAdapter
  4. Alternative PagerAdapter RecyclerView. Adapter
  5. RegisterOnPageChangeCallback replace addPageChangeListener
  6. ViewPager2 supports right-to-left (RTL) layout support, vertical support
  7. ViewPager2 supports disabling user input (setUserInputEnabled, isUserInputEnabled)

Five, simple use

1. Introduce dependencies

Implementation 'androidx. Viewpager2: viewpager2:1.0.0' implementation 'androidx. Recyclerview: recyclerview: 1.1.0' / / ViewPager 2 requires a RecycleView adapterCopy the code

2. XML layout

<androidx.viewpager2.widget.ViewPager2
        android:id="@+id/vp_rg"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/rg_vp" />
Copy the code

3, Adapter

import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; import androidx.viewpager2.adapter.FragmentStateAdapter; import java.util.ArrayList; import java.util.List; /** * CreateTime: 2021/10/30 21:32 * Author: */ public class extends FragmentStateAdapter {private List< class > fragments; public RgAdapter(@NonNull FragmentActivity fragmentActivity) { super(fragmentActivity); if (fragments == null) { fragments = new ArrayList<>(); } } public void addFragment(Fragment fragment) { if (fragments ! = null) { fragments.add(fragment.getClass()); } } @NonNull @Override public Fragment createFragment(int position) { try { return (Fragment) fragments.get(position).newInstance(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } return null; } @Override public int getItemCount() { return fragments.size(); }}Copy the code

4. Activity logic

package com.example.viewpager2.withRadioGroup; import androidx.appcompat.app.AppCompatActivity; import androidx.viewpager2.widget.ViewPager2; import android.os.Bundle; import android.widget.RadioButton; import android.widget.RadioGroup; import com.example.viewpager2.R; public class RgActivity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener { private ViewPager2 vpRg; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_rg); RgAdapter adapter = new RgAdapter(this); RadioGroup rgVp = findViewById(R.id.rg_vp); vpRg = findViewById(R.id.vp_rg); rgVp.setOnCheckedChangeListener(this); vpRg.setAdapter(adapter); adapter.addFragment(new HomeFragment()); adapter.addFragment(new MessageFragment()); adapter.addFragment(new MyFragment()); vpRg.setCurrentItem(0); vpRg.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { @Override public void onPageSelected(int position) { super.onPageSelected(position); switch (position) { case 0: ((RadioButton) findViewById(R.id.rb_home)).setChecked(true); break; case 1: ((RadioButton) findViewById(R.id.rb_msg)).setChecked(true); break; case 2: ((RadioButton) findViewById(R.id.rg_my)).setChecked(true); break; }}}); } @Override public void onCheckedChanged(RadioGroup group, int checkedId) { switch (checkedId) { case R.id.rb_home: vpRg.setCurrentItem(0); break; case R.id.rb_msg: vpRg.setCurrentItem(1); break; case R.id.rg_my: vpRg.setCurrentItem(2); break; }}}Copy the code

There needs to be said is registerOnPageChangeCallback method, this method can listen to the ViewPager 2 interface changes, thus to operate other controls

Vi. DiffUtil

If you have used DiffUtil, you know its benefits. It doesn’t matter if you haven’t used DiffUtil. Let me tell you something.

  • It can perform a partial refresh by calculating the difference between two lists, which we normally usenotifyDataSetChanged(); Is a mindless refresh operation that refreshes the entire list and is not very performance or visually friendly.
  • The differential evolution algorithm is used to calculate the minimum coefficient of the update.
  • Note that if you have a large amount of list data, it is recommended to perform this operation in the background thread. DiffResult is executed in the main thread by default.
  • If movement detection is enabled, it takes an additional O (N ^2) time, where N is the total number of items added and removed. If your list is already sorted by the same constraint (for example, a timestamp created for a list of posts), you can disable movement detection to improve performance.