OnResume() not called in Fragment using tabLayout and ViewPager
Asked Answered
L

2

12

i'm developing an app using tabLayout.

I've a problem: When I try to reactivate a Fragment, the method OnResume is non called.

This is my activity:

 private void init() {
    fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Snackbar.make(view, "Nuovo Ticket", Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show();
        }
    });


    TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
    tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);

    final ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
    final PagerAdapter adapter = new PagerAdapter
            (getSupportFragmentManager(), tabLayout.getTabCount());
    viewPager.setAdapter(adapter);

    tabLayout.setupWithViewPager(viewPager);
}

I use a FragmentStatePagerAdapter like this:

public class PagerAdapter extends FragmentStatePagerAdapter {
int mNumOfTabs;

public PagerAdapter(FragmentManager fm, int NumOfTabs) {
    super(fm);
    this.mNumOfTabs = NumOfTabs;
}

@Override
public Fragment getItem(int position) {

    switch (position) {
        case 0:
            return new LavorazioneFragment();
        case 1:
            return new PendingFragment();
        case 2:
            return new StoriciFragment();
        default:
            return null;
    }
}

@Override
public int getCount() {
    return mNumOfTabs;
}

}

When i reactivate the TAB1 Fragment from TAB3 Fragment (the last one), the OnResume Method is called. But, for example,

When I try to reactivate the first tab from the second, never called.

Lido answered 16/2, 2016 at 15:9 Comment(4)
Is there a reason you're not using setupWithViewPager()?Enchanter
@Daniel Nugent No reason! how i can use it?Lido
guides.codepath.com/android/…Enchanter
@DanielNugen I've update my code like your suggestion but not solve my problem.Lido
L
36

I've solved the problem. I use setUserVisibleHint(boolean isVisibileToUser) instead onResume(). Like this:

 @Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if(isVisibleToUser) {
        init();
    } else {

    }
}

Thank you all!

Lido answered 17/2, 2016 at 7:41 Comment(6)
As a note I believe it is critical to mention that this DOES NOT get called when returning or switching from activities. It also DOES NOT get called when the device awakens from SLEEP or REST mode. This only gets called when the user switches between tabs either by swiping between the fragments or manually pressing the tab. So do not forget to include logic within your onResume and onPause methods.Kelly
Lots of lengthy posts on SO about this. Several mention the return POSITION_NONE approach. I didn't try that - messing with the adapter, I try to refrain from. Applying this solution at the fragment level, found it to be very straight forward to incorporate. Nice - thanksMercurialism
@gnB the other questions are about refreshing the fragments, not calling onResume.Wreathe
@Emanuel My reasoning for this comment is from a purely functional point of view - not implementation specific. With onResume there is the common case where you need to refresh a fragment.. it was in the background, there were some updates to the model, and now the fragment is coming back to the foreground. Where onResume wasn't working for me reliably in a ViewPager setup, every time a pager fragment comes back to foreground .. the solution in this posted answer does do the refresh reliably. Furthermore - the simplicity here I think makes for an elegant design choice. Just my $0.02Mercurialism
Watch out! "This method may be called outside of the fragment lifecycle. and thus has no ordering guarantees with regard to fragment lifecycle method calls" - I experienced setUserVisibleHint(false) getting called before onCreate. So make sure you null check Views etcZippy
This method is is now deprecated.Deferment
D
8

The accepted answer did not work for me. However, I found a solution to the problem.

Just initialise your FragmentStatePagerAdapter with the following constructor:

public MyPagerAdapter(FragmentManager fm, int behaviour) {
    super(fm, behaviour);
}

like this :

MyPagerAdapter myPagerAdapter = new MyPagerAdapter(getChildFragmentManager(), FragmentStatePagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
Dullish answered 23/12, 2019 at 10:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.