This article will take you step by step to write a LazyFragment from the beginning. According to the process of writing step by step, you can also try it yourself and write along with it. Finally, according to the problems encountered to improve, online search is not perfect, or write a!
Making portal
What is lazy loading?
The question seems silly. But think about it: lazy loading is loading data and views, or data? (I thought about that at first…) Data, of course, how can you prevent the view from loading! There is nothing you can do to prevent the life cycle of a Fragment function from executing, so you can only load data on the currently displayed Fragment
How do you know if the current page is the Fragment being displayed?
There are two methods available in the source code
Public void setUserVisibleHint(Boolean isVisibleToUser) {}Copy the code
and
Public void onHiddenChanged(Boolean hidden) {}Copy the code
So I’m just going to try these two methods very simply and I’m going to write a Viewpager+Fragment with a cache offscreenPageLimit of 1.
When you open your app
We can see the home pageBadHomeFragment
theSetUserVisibleHint () method
To perform thetwo
! Return false invisible and true visible. And it doesn’t matter what Fragment it issetUserVisibleHint()
Both run faster than the life cycle
When switching to the second Fragment
Cut back to home page Fragment
When a Fragment that has run through the life stream is displayed again, it will only walksetUserVisibleHint()
(Ignore the onHiddenChange method for now)
If you want to load the data into the visible state of setUserVisibleHint(), you’re done.
So let’s write it this way
Call the interface in loadData in the sub-fragment to get the data and then assign a value to the control
The result! Error!!!!! Your control is null, I can see why null. Because when you enter your appsetUserVisibleHint
Fragment does not load the layout before the life cycle, null of course
Can I just add a variable to see if the layout is loaded?
The result? Home page Fragment not executedonLoadData
Method, clickTwoFragment
And they did. Why? BecausesetUserVisibleHint
Even earlier, andTwoFragment
It has already been initialized, so the data can only be loaded when you click past.
So we have to distribute the loading event once more in the life cycle, taking the loading event as a method
Look at the log from opening the app to clicking on the third Fragment. Everyone is loading data normally. It seems to be normal
Then try to jump from the first page to the last page, you will find some pages in the middle inexplicable callStopLoadData
Function?? This is obviously a problem, and it seems that we can’t simply distribute it in visible state
We’re thinking about it,LoadData
Called when the Fragment is visible,StopLoadData
Called when the Fragment is not visible. In fact, this is not completely said, should be fromInvisible state to visible state
Load data,When you go from visible to invisible
Stop. So we have to use a variable to record the visible state
You can see that in terms of switching, the events that are distributed are already normalonStop
theCurrentVisibleStatus status reset!
The above is our common online lazy loading, but there will be two problems
What happens when you jump to another page and come back?
It doesn’t do anything, it just doesn’t distribute the event that loaded the data when it comes back. So I’m going to add this code, and I’m going to use a variable to say, I don’t need to, but I think if you jump to another page and come back to the Fragment, it should change, so distribute it
What about having a viewpager+Fragment in a child Fragment?
I’m going to get rid of the other logs, just to make it clear
I added a ViewPager to the TowFragment with TowFragment1 and 2 in it
Enter the App, you can see that the father has not displayed, the son loaded the data first?
In addition, the two sons in the TowFragment at the bottom Tab were indifferent. Only the App was loaded when the App was just opened, and the method to stop the loading was not called. No event was distributed to the son at all
So we have to do a little bit more judgment based on the state of the father and the son to solve the first problem, the parent Fragment is not displayed, the child Fragment loaded data. The problem is very simple. We just need to check if there is a parent Fragment and if it is visible when distributing the event that loads the data. It is ok
This method in the Fragment source code can solve the above problem
For example, exit the method if the parent Fragment is not visible and cannot be distributed
However, the problem is that no matter how you switch, the sub-fragment does not send events that load or stop loading data. Why is that?
As you can see from the beginning, the child Fragment also calls the setUserVisibleHint method twice when entering the HomeFragment, setting its visible state to True before entering. The following distribution event is invalid.
So I decided to call the dispatch event again when I entered the parent Fragment, actually loading the child Fragment’s data, for example
You can see that the switching is normal
The SmartRefresh control is added to imitate the loading mode of Microblogging (of course, it can only be simple to imitate). I will make up for it when I have time!