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 pageBadHomeFragmenttheSetUserVisibleHint () methodTo 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 appsetUserVisibleHintFragment 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 executedonLoadDataMethod, clickTwoFragmentAnd they did. Why? BecausesetUserVisibleHintEven earlier, andTwoFragmentIt 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 callStopLoadDataFunction?? This is obviously a problem, and it seems that we can’t simply distribute it in visible state

We’re thinking about it,LoadDataCalled when the Fragment is visible,StopLoadDataCalled when the Fragment is not visible. In fact, this is not completely said, should be fromInvisible state to visible stateLoad data,When you go from visible to invisibleStop. 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 normalonStoptheCurrentVisibleStatus 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!