SoFunction
Updated on 2025-03-11

Optimization solution for stuttering when using ViewPager to quickly switch Fragment

When the ViewPager switches to the current Fragment, the Fragment will load the layout and display the content. If the user quickly switches the ViewPager at this time, that is, the Fragment needs to load UI content, and frequently switches the Fragment, it is easy to cause lag (similar to loading pictures while sliding quickly while ListView is running).

Optimization solution:

Lightweight

If the Fragments loaded by ViewPager are relatively lightweight, appropriately streamlining the layout of the Fragment can improve the speed of Fragment loading, thereby reducing lag.

2. Prevent the Fragment from being destroyed

When switching ViewPager, if the Fragment is frequently destroyed and loaded, it is easy to cause lag. Preventing the destruction of the Fragment can effectively alleviate lag.

(1) Overriding the destroyItem method in PagerAdapter can prevent the destruction of the Fragment

@Override    
public void destroyItem(ViewGroup container, int position, Object object) {      
//(container, position, object);    
}

(2) Through the setOffscreenPageLimit() method of PagerAdapter, several Fragments can be retained. Appropriately increasing the parameters can prevent Fragments from being frequently destroyed and created.

risk:When there are many Fragments, some low-end models are prone to OOM problems.

Content delay loading

(1) Description

When switching to the current Fragment, the content of the Fragment is not loaded immediately, but a simple empty layout is loaded first, and then a delay task is started, with the delay time being T. When the user switches to another Fragment and the residence time is lower than T, the delay task will be cancelled.

(2) Specific operations

First, set up the delay task

private Runnable LOAD_DATA = new Runnable() {    
    @Override    
    public void run() {      
     // Here the data content is loaded on the Fragment    }  
};

Start a task

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
  //Initialize the view, it is best to set a progress dialog box here to prompt the user to load data  initView();
  //Start the task, set here to start loading data after 500 milliseconds (LOAD_DATA, 500)  return view;
}

If the user switches to another fragment, cancel the task

//Overloading method to determine whether the Fragment is visible@Override  
public void setUserVisibleHint(boolean isVisibleToUser) {    
(isVisibleToUser);    
if(!isVisibleToUser)        
  (LOAD_DATA);
}

(3) Note

Use setUserVisibleHint to determine whether the user switches to other Fragments. This approach has a flaw, because the delay task will be canceled when the ViewPager starts to slide. When the sliding offset is insufficient, the ViewPager will continue to roll back to the current Fragment, causing the loading task of the current Fragment to be cancelled without restarting the load task.

The method I use here is to add an OnPageChangeListener to the ViewPager, and the onPageSelected(position) of the listener can listen to which Fragment the ViewPager is currently switching to, cancel the lazy loading task of other Fragments here.

Summarize

The above is the entire content of this article. I hope that the content of this article has certain reference value for your study or work. Thank you for your support. If you want to know more about it, please see the following links