1

As topic states I'm trying to implement swipable tabs using Fragments and ActionBar. I've iplemented it successfully using ActionBarSherlock and code from examples with the TabsAdapter class (subclass to FragmentPageAdapter). Some of the fragments should be able to show a new tab in the same tab spor, and this is where the problem arises. I really can't figure out how to replace a fragment in the pager with a new one. I've googled and tried out a lot of stuff.

I can replacie the fragment in the internal collection holding the fragments classes inside the FragmentPageAdapter, thus making the new Fragment available to the getItem method but that doesn't do it as I can't figure out how to update the pager to show the new Fragment. Even after switching to another Tab and going back I still get the old Fragment which I suppose is being cached somewhere by the pager. So is there a way to notify an update to the pager?

Maybe I should just forget using FragmentPageAdapter ? In that case what is the right way to get all this functionallity happen?

P.S. If you want to see my code let me know, but it's basicly the same as in the examples and the problem is more general I think

tshepang
  • 12,111
  • 21
  • 91
  • 136
user1293081
  • 331
  • 1
  • 3
  • 12

2 Answers2

0

When you use a ViewPager it keeps the visible page/fragment in memory in addition to pages/fragments that you can navigate to. In addition to this, if the ViewPager is using a FragmentPagerApdapter it keeps the views in memory for the life of the activity.

I answered a similar post to yours above removing a fragment which can be found here. Your case is an extension of this, removing and then adding something else.

https://stackoverflow.com/a/10399127/629555

Basically, you need to use a FragmentStatePagerAdapter, override the getItemPosition method to return PagerAdapter.POSITION_NONE and make sure you call .notifyDataSetChanged(); on your adapter when you want it changed.

The answer to the link above covers this in much more detail and provides a code example.

Community
  • 1
  • 1
Louth
  • 11,401
  • 5
  • 28
  • 37
  • Thanks, I've tried it out and it works! But does the use FragmentStatePagerAdapter of means that the fragments are getting reloaded every time i switch/swipe between them or are they still kept in the memory and just reloaded when notifyDataSetChanged is called? – user1293081 May 05 '12 at 23:08
  • `FragmentStatePagerAdapter` will unload/load every time you swipe. Its a trade off between processing power and memory with the `Fragment` related `PagerAdapter`. – Louth May 05 '12 at 23:19
  • Ok, so there is no way to use FragmentPageAdapter and just manually force a reload? Would preffer that to make it smoother. – user1293081 May 06 '12 at 09:15
  • Or is there a totally different way of doing this? A way that maybe also will make handling of back-stack easier? – user1293081 May 06 '12 at 09:54
  • I couldn't figure out a way to do it with the `FragmentPagerAdapter'. I guess you could write your own `PagerAdapter`. – Louth May 06 '12 at 10:54
0

What about keeping a reference to the fragments in the adapter my self with the FragmentStatePagerAdapter ? Then I have them both saved in the memory but also have full control of deletion. Is there anything bad I'm missing with this approach and will I run into problems later on? Also I've changed so the fragments are passed on as objects and not classes, thus leaving the initiation outside the pager. Any problems with this?

Attaching my code of the adapter:

public static class TabsAdapter extends FragmentStatePagerAdapter  implements
ActionBar.TabListener, ViewPager.OnPageChangeListener {
    private final Context mContext;
    private final ActionBar mActionBar;
    private final ViewPager mViewPager;
    private final ArrayList<Fragment> mTabs = new ArrayList<Fragment>();


    public TabsAdapter(SherlockFragmentActivity activity, ViewPager pager) {
        super(activity.getSupportFragmentManager());
        mContext = activity;
        mActionBar = activity.getSupportActionBar();
        mViewPager = pager;
        mViewPager.setAdapter(this);
        mViewPager.setOnPageChangeListener(this);
    }

    public void addTab(ActionBar.Tab tab, Fragment fragment) {          
        tab.setTag(fragment);
        tab.setTabListener(this);
        mTabs.add(fragment);
        mActionBar.addTab(tab);


        notifyDataSetChanged();
    }           

    public void replaceTab(ActionBar.Tab tab, Fragment fragment, int position) {

        tab.setTag(fragment);
        tab.setTabListener(this);
        mTabs.set(position, fragment);
        notifyDataSetChanged(); 
    } 

    @Override
    public int getCount() {
        return mTabs.size();
    }

    @Override
    public Fragment getItem(int position) {
        return mTabs.get(position);
    }

    @Override
    public void onPageScrolled(int position, float positionOffset,
            int positionOffsetPixels) {
    }

    @Override
    public void onPageSelected(int position) {
        mActionBar.setSelectedNavigationItem(position);
    }

    @Override
    public void onPageScrollStateChanged(int state) {
    }

    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        Object tag = tab.getTag();
        for (int i = 0; i < mTabs.size(); i++) {
            if (mTabs.get(i) == tag) {
                mViewPager.setCurrentItem(i);
            }
        }
    }

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

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

    @Override
    public int getItemPosition(Object object){
        return PagerAdapter.POSITION_NONE;
    }
}
user1293081
  • 331
  • 1
  • 3
  • 12
  • If you're adding new information to your question, you should edit your question, not add a new answer. – BoltClock May 07 '12 at 08:52
  • I didn't really saw it as the same question. First question ask for solutions, second is a solution (which I would like some response on). – user1293081 May 07 '12 at 09:32