Reprint Please specify source: http://blog.csdn.net/linglongxin24/article/details/53205878
This article is from "Dylanandroid's blog"
Viewpager+fragment Lazy Loading problem solution in Android
In Android we often use the viewpager+fragment combination. However, one of the big headaches is that when we go to load the data,
Due to the internal mechanism of Viewpager, it defaults to at least one preload. It was depressing, so I thought I'd wrap up a fragment to solve the problem.
1. A preliminary study of problems
The article begins with the pre-loading mechanism of viewpager. So, can we set the pre-load of Viewpager to 0, do not solve the problem?
vp.setOffscreenPageLimit(0);
After testing, we found that this is not the case, why? Let's take a look at the source code of Viewpager's Setoffscreenpagelimit () method
Private Static Final intDefault_offscreen_pages =1;/** * Set The number of pages that should is retained to either side of the "current page" in the View hierarchy I n an idle state. Pages beyond this * limit is recreated from the adapter when needed. * * <p>this is offered as an optimization. If you know in advance the number * of pages you'll need to support or has lazy-loading mechanisms in place * o n your pages, tweaking this setting can has benefits in perceived smoothness * of paging animations and interaction. If you have a small number of pages (3-4) * So you can keep active all at once, less time would be spent in layout fo R * Newly created view subtrees as the user pages back and forth.</p> * * <p>you should keep this Limit low, especially if your pages has complex layouts. * This setting defaults to 1.</p> * *@paramLimit how many pages would be kept offscreen in a idle state. */ Public void Setoffscreenpagelimit(intLimit) {if(Limit < Default_offscreen_pages) {LOG.W (TAG,"requested offscreen page limit"+ Limit +"too small; Defaulting to "+ default_offscreen_pages); Limit = Default_offscreen_pages; }if(Limit! = Moffscreenpagelimit) {moffscreenpagelimit = limit; Populate (); } }
We found that even if you set it to 0, it will be set to the default value of 1 after the inside judgment. So this method is not feasible.
2. Further exploration of the problem
We found that there is a Setuservisiblehint (Boolean Isvisibletouser) method in fragment that tells the user whether the UI is visible to the user, so what happens when we load the data here?
Why is that?
Because Viewpager will load a lot of fragment, in order to save content and so on fragment will not be visible at some time call Ondestroyview () to destroy the user interface, but fragment instance is still in, so the first load can be no problem,
But once again, when the first fragment is loaded, the UI is visible to the user but the view is not initialized.
3. Final Solution
PackageCn.bluemobi.dylan.viewpagerfragmentlazyload;ImportAndroid.os.Bundle;Importandroid.support.annotation.Nullable;ImportAndroid.support.v4.app.Fragment;ImportAndroid.text.TextUtils;ImportAndroid.view.LayoutInflater;ImportAndroid.view.View;ImportAndroid.view.ViewGroup;ImportAndroid.widget.Toast;/** * Can be lazy loaded fragment * Created by Yuandl on 2016-11-17. */ Public Abstract class lazyloadfragment extends Fragment { /** * Whether the view has been initially initialized */ protected BooleanIsinit =false;protected FinalString TAG ="Lazyloadfragment";@Nullable @Override PublicViewOncreateview(Layoutinflater inflater, @Nullable viewgroup container, @Nullable Bundle savedinstancestate) {View view = Inflater.inflate (Setcontentview (), Container,false); Isinit =true;/** to load data when initializing **/Iscanloaddata ();returnView }/** * Whether the view is already visible to the user, the system's method */ @Override Public void Setuservisiblehint(BooleanIsvisibletouser) {Super. Setuservisiblehint (Isvisibletouser); Iscanloaddata (); }/** * Can load data * conditions that can load data: * 1. View already initialized * 2. View visible to User */ Private void Iscanloaddata() {if(Getuservisiblehint () && isinit) {lazyload (); } }/** * View destroyed when the state of fragment is initialized to False */ @Override Public void Ondestroyview() {Super. Ondestroyview (); Isinit =false; }protected void Showtoast(String message) {if(! Textutils.isempty (message)) {Toast.maketext (GetContext (), message, Toast.length_short). Show (); } }/** * Set fragment the layout to display * * @return layout layoutid */ protected Abstract int Setcontentview();/** * When the view is initialized and visible to the user to actually load the data */ protected Abstract void Lazyload();}
4. Usage
Lazyloadfragment is an abstract class that can be inherited as a basefragment.
(1). Use the Setcontentview () method to load the layout to be displayed
(2). Lazyload () method to load data
PackageCn.bluemobi.dylan.viewpagerfragmentlazyload;ImportAndroid.util.Log;/*** Created by Yuandl on 2016-11-17.*/ Public class Fragment1 extends lazyloadfragment { @Override Public int Setcontentview() {returnR.LAYOUT.FM_LAYOUT1; }@Override protected void Lazyload() {String message ="Fragment1"+ (Isinit?)"Data can be loaded initially":"No initialization cannot load data"); Showtoast (message); LOG.D (TAG, message); }}
5. Look at the effect screen
6.GitHub
Viewpager+fragment Lazy Loading problem solution in Android