简体   繁体   中英

Swipable and replacable tabs, Fragments and ActionBar

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?

PS 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

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.

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;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM