Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I don't want to refresh fragment on change

I have 3 fragments... with their 3 navigation tabs.

The problem is that if i'm on the first tab, and i click the third.. when I click another time the first, it reloads all the fragment. If I click the second tab (in the middle) and I click the first, it doesn't reload.

My objective is that I don't want to refresh my fragments never!

How can I do it?

My code is:

public class TabsPagerAdapter extends FragmentPagerAdapter {

    public TabsPagerAdapter(FragmentManager fm) {
        super(fm);
    }
// Return Items
    @Override
    public Fragment getItem(int index) {

        switch (index) {
        case 0:
            return new Retos();
        case 1:
            return new Amics();
        case 2:
            return new Ranking();
        }

        return null;
    }

    @Override
    public int getCount() {
        // get item count - equal to number of tabs
        return 3;
    }

}

And this :

public class Perfil extends ActionBarActivity implements ActionBar.TabListener{

private ViewPager viewPager;
private TabsPagerAdapter mAdapter;
private ActionBar actionBar;
private SearchView mSearchView;
private TextView mStatusView;
// Tab titles
private String[] tabs = { "TAB1", "TAB2", "TAB3" };



@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.perfil);


    // Initilization
    viewPager = (ViewPager) findViewById(R.id.pager);
    actionBar = getSupportActionBar();
    mAdapter = new TabsPagerAdapter(getSupportFragmentManager());

    viewPager.setAdapter(mAdapter);
    actionBar.setHomeButtonEnabled(true);
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);    


    /** Creating fragment1 Tab */
    Tab tab = actionBar.newTab()
        .setText("TAB1")
        .setTabListener(this);

    actionBar.addTab(tab);

    /** Creating fragment2 Tab */
    tab = actionBar.newTab()
        .setText("TAB2")
        .setTabListener(this);
        //.setIcon(R.drawable.ic_action_group);

    actionBar.addTab(tab);

    /** Creating fragment3 Tab */
    tab = actionBar.newTab()
        .setText("TAB3")
        .setTabListener(this);

    actionBar.addTab(tab);




    /**
     * on swiping the viewpager make respective tab selected
     * */
    viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {

        @Override
        public void onPageSelected(int position) {
            // on changing the page
            // make respected tab selected
            actionBar.setSelectedNavigationItem(position);

        }

        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {
        }

        @Override
        public void onPageScrollStateChanged(int arg0) {
        }
    });
}


@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}

@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
    // on tab selected
    // show respected fragment view
    viewPager.setCurrentItem(tab.getPosition());
}

@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}

}

like image 635
Jaume Colom Ferrer Avatar asked Jul 22 '14 15:07

Jaume Colom Ferrer


People also ask

How do you stop a fragment from recreating?

Calling setRetainInstance(true) will prevent the Fragment from being re-created. But, right now the Activity is always re-creating the DrawerFragment and forcefully re-creating the HomeFragment , resulting in the behavior you are seeing. In your Activity. onCreate() check the savedInstanceState is null .


2 Answers

viewPager.setOffscreenPageLimit(C_FRAGMENTS_TO_KEEP_IN_MEMORY);

C_FRAGMENTS_TO_KEEP_IN_MEMORY is the number of tabs at right and left of the current selected tab to keep in memory. So in your case should be 2.

Please be sure that you are NOT creating a new fragment instance each time you call the getItem method in you viewpager adapter.

Check the @Rarw answer in this page.

like image 166
Sotti Avatar answered Oct 26 '22 05:10

Sotti


Try setting your ViewPager offScreenPageLimit to cover the number of fragments you are trying to load. OffScreenPageLimist keeps fragments alive in an idle state when they are not visible. I don't see that value set in your code and based on what you're describing, that fragments keep recycling, it sounds to me like you're using the default state of 1, which will only retain one of the fragments off screen and not both.

Some caveats, this approach only really works if you know in advance how many fragments you will need since if you're dynamically adding and removing fragments its hard to know how many if any to retain.

UPDATE

This is likely why you're pages are refreshing:

@Override
public Fragment getItem(int index) {

    switch (index) {
    case 0:
        return new Retos();
    case 1:
        return new Amics();
    case 2:
        return new Ranking();
    }

    return null;
}

You keep returning a new fragment each time you switch id. What you should do something like this:

case 0:
    if(mRetrosFragment == null)
          mRetrosFragment = new Retros();
    return mRetrosFragment;

This way you stop recreating the fragment every time the tab changes and instead retain that instance.

like image 21
Rarw Avatar answered Oct 26 '22 04:10

Rarw