-1

I have implemented a View Pager in my app. It slides between to fragments, the problem is, even if only the first fragment is being display, the other fragment gets created. That causes problems because, in the second fragment I'm displaying a Loading Bar and this way it shows in the first fragment instead of the second one.

This is my ViewPager code:


class FragmentViewPagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) {

    override fun getItem(position: Int): Fragment {
        if (position == 0){
            return VentFragment()
        }
        return ConversationsFragment()
    }

    override fun getCount(): Int {
        return 2
    }

}

In the second fragment I call the Loading Bar this way in onCreateView:

 loading = ProgressDialog(context)

        loading.setTitle(getString(R.string.loading))
        loading.setMessage(getString(R.string.fetching_your_data))
        loading.setCanceledOnTouchOutside(false)
        loading.show()

Is it because of the context? I can't seem to find the bug...

André Nogueira
  • 3,363
  • 3
  • 10
  • 16
  • 1
    The offscreen page limit is at least 1. The second fragment WILL be created inside the ViewPager. If you don't want that, don't use a ViewPager for it. – EpicPandaForce Feb 18 '20 at 22:10

3 Answers3

1

the problem is, even if only the first fragment is being display, the other fragment gets created

That is the way ViewPager works. It needs the second fragment to be available in order to transition to it when the user swipes, rather than wait for you to create it after the user has started swiping.

in the second fragment I'm displaying a Loading Bar and this way it shows in the first fragment instead of the second one

Your second fragment has a bug. A fragment — particularly one a ViewPager — should not be modifying UI that lives outside of the fragment itself. If you fix this bug, your problem with ViewPager should go away.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • 1
    @AndréNogueira: A fragment should not be displaying a dialog just by virtue of being created. So either switch to an in-fragment progress indicator or do not show the `ProgressDialog` until the user does something that requires it (e.g., clicks a button to start the work). – CommonsWare Feb 18 '20 at 22:17
0

So it is possible to do "lazy loading" of UI data with ViewPager (I do), so that data and the loading bar is only displayed when the page is selected.

Update:

I would recommend you move to ViewPager2 as ViewPager2 correctly supports the Fragment lifecycle unlike ViewPager.

This means you can easily update your placeholder (or start your loading bar) in the Fragment's onResume Method

I've just done a full example using ViewPager2 using the ViewPager method, see for https://stackoverflow.com/a/60253406/2373819 (Update2 has full example and is similar to how you can do it if you still want to use ViewPager)

Note both methods will cause a screen update to display the correct (latest) data, this can be during the transition or with ViewPager2 and onResume as soon as the transition has finished, but then you can have the incorrect old data or have a second screen update to have the correct up to date data.

Andrew
  • 8,198
  • 2
  • 15
  • 35
  • I'd say, from a purely UX/UI point of view, that a view updating, after transitioning, ruins the seemless scrolling/transitioning experience that a `ViewPager` offers. Also updating a `Fragment` thats implements or has a "update" method breaks tradition with `Fragment` lifecycle hook methods. – Mark Feb 18 '20 at 22:27
  • Yes the UI is updated during transition, but depending on what you are updating is can be barely noticeable unless swipe the screen really slowly, As for breaks a `Fragment` lifecycle, The lifecycle has got to a "active" state as soon as the page transition starts, so the update is just like the user pressing a refresh button or other event. If you think that a Fragment should never be changed when "active" then you understand the lifecycle wrong. – Andrew Feb 18 '20 at 22:54
  • Just as you are allowed to answer a question, I am aforded the privilege of critiqueing your answer. Thanks for acknowledging that there will be an update delay as this justifies my comment. – Mark Feb 18 '20 at 23:32
  • Actually thanks for the critique, It made me check my answers and come up with a better answer. While is was true that ViewPager is resumed when the view is updating, this is not the case for ViewPager2 – Andrew Feb 18 '20 at 23:37
  • 1
    Note that ViewPager2 works exactly like ViewPager1's `BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT` regarding the lifecycle. – ianhanniballake Feb 19 '20 at 04:12
  • @ianhannilballake you are right Androidx's versions of both changed to capping the state at "Started" recently, so it depends on where you are getting ViewPager1 from (for me this was a work around pre Androidx and this change) – Andrew Feb 19 '20 at 10:50
0

Instead of making network calls in onCreate of the fragment, you can make them in onResume(). So when the fragment gets resumed, then only the call will be made and loader will be shown.

hemdroid
  • 61
  • 1
  • 7