How to load data only for current fragment in ViewPager?

from the CommonsWare Community archives

At May 7, 2019, 6:34pm, _shahdhaval asked:

Hello. I have a question regarding ViewPager.

Consider the following situation:

There is a ViewPager containing 3 fragments. [A, B, C]
Normally, when I instantiate ViewPager, the lifecycle methods of the first fragment and second fragment is called.

In my case, I am fetching data from the network in Fragment’s onStart method so by default both fragments are fetching data from the network at the same time.

How can we prevent this behavior?

I want to know if the following behavior is possible or not?

When I go to fragment A -> it should call network API
When I swipe to fragment B -> it should call network API
and when I move to fragment C -> it should call network API.

Is this possible to achieve?

At May 7, 2019, 6:54pm, mmurphy replied:

The user may want that behavior.

The problem with what you are seeking is that the user now has to wait. They swipe to fragment B, and you are not ready, so they sit and watch some progress indicator for a while until your network I/O is done.

That being said, you could have the activity or fragment that hosts this ViewPager tell a fragment when it is the currently-visible page, and do your network I/O at that point. The ViewPager host would use an OnPageChangedListener to find out about the page changes and call a method on the associated fragment.

At May 15, 2019, 11:28am, relaxedsoul replied:

@mmurphy sometimes the content of the second fragment depends on the content of the first one.

In my cases, I want the second fragment to wait until the first fragment loads the data. Only after that, I know the second fragment’s behavior.

The solution is to create some interface for the fragment.

interface TabView {
    fun prepareTab()
    fun onTabOpened()
    fun onTabClosed()

make the fragment to implement it.
When the tab is changed, call the correct methods in the interface casting fragment on it.

(fragment as TabView).onTabOpened()

To save the user’s time and load data before the tab is opened, but after the first tab finishes some important updates, we will call the following method:

(fragment as TabView).prepareTab()
, for the fragment which is the next after the current.

At May 15, 2019, 11:45am, mmurphy replied:

My guess is that you really mean “the data that goes into the second fragment is related to the data that goes into the first fragment”.

IMHO, you should mean “I want to load both fragments’ data in and around the same time, since there is a data dependency”.

IMHO, the solution is to get the data-loading code out of the fragments and into a shared viewmodel, where the fragments can then react to the data being loaded once it is ready. That way, you are not blocking the data load for fragment B any more than is necessary.

At May 15, 2019, 1:14pm, relaxedsoul replied:

Sorry, the data is independent. But it is huge. The second fragment should wait until the first fragment loads the content to start load its own. And also I don’t store it. It’s web content.

At May 15, 2019, 1:18pm, relaxedsoul replied:

So, there is not data dependency, no possible shared viewmodel.

And also, there are some background tasks performed. They are started not because of the first fragment shown, but because the whole activity is opened. I just wanted to delay the loading of all other tabs to allow the current tab to have access to the network without any limitations.

In this context the current tab should be understood as the first shown, the default tab.