user1014917
user1014917

Reputation: 681

Replacing a Fragment/Tab in a Viewpager

I am currently trying to make framework for my future apps. I really like the ActionBar and the ViewPager, but miss a feature. I need to replace a Fragment/Tab in runtime.

Using the offical example, I would love to see something like a replaceTab(), but the Fragment itself isn't updated, no matter what I do.

Upvotes: 6

Views: 4657

Answers (4)

Arnaud SmartFun
Arnaud SmartFun

Reputation: 1593

You have to use a FragmentPagerAdapter to handle your fragment changes. There are 3 important things:

  • remove the previous fragment if it exists.

  • call notifyDataSetChanged() to refresh the list of pages.

  • return POSITION_NONE in getItemPosition if it's asking for an old fragment.

Here is the code I use with a Left and a Right page. I change dynamically the fragments depending on what the user does.

public class MyPager extends ViewPager {

    private MyPagerAdapter mMyPagerAdapter;

    public MyPager(Context context, FragmentActivity activity) {
        super(context);

        mMyPagerAdapter = new MyPagerAdapter(activity.getSupportFragmentManager());
        setAdapter(mMyPagerAdapter);

    }
    public void replaceLeftFragment(Fragment fragment) {
        mMyPagerAdapter.replaceLeftFragment(fragment);
    }
    public void replaceRightFragment(Fragment fragment) {
        mMyPagerAdapter.replaceRightFragment(fragment);
    }
}

public class MyPagerAdapter extends FragmentPagerAdapter {

    private FragmentManager mFragmentManager;
    private Fragment mLeftFragment;
    private Fragment mRightFragment;

    public MyPagerAdapter(FragmentManager fm) {
        super(fm);
        mFragmentManager = fm;
    }

    @Override
    public Fragment getItem(int position) {
        if (position == 0) {
            return mLeftFragment;
        } else {
            return mRightFragment;
        }
    }

    @Override
    public int getCount() {
        final int nbLeft = (mLeftFragment == null) ? 0 : 1;
        final int nbRight = (mRightFragment == null) ? 0 : 1;
        return (nbLeft + nbRight);
    }

    public void replaceLeftFragment(Fragment fragment) {
        if (mLeftFragment != null) {
            mFragmentManager.beginTransaction().remove(mLeftFragment).commit();
        }
        mLeftFragment = fragment;
        notifyDataSetChanged();
    }
    public void replaceRightFragment(Fragment fragment) {
        if (mRightFragment != null) {
            mFragmentManager.beginTransaction().remove(mRightFragment).commit();
        }
        mRightFragment = fragment;
        notifyDataSetChanged();
    }

    @Override
    public int getItemPosition(Object object) {
        if ((object!=mLeftFragment) && (object!=mRightFragment)) {
            return POSITION_NONE;
        }
        return super.getItemPosition(object);
    }

}

Upvotes: 2

3c71
3c71

Reputation: 4511

Very close to what you want, I needed to add fragment (at the end) to a ViewPager, and did this:

    FragmentTransaction ft = fragmentManager.beginTransaction();
    new_fragment = Fragment.instantiate(activity, class_name, args);

    // The below code removes old fragment and adds the new one at the end.
    ft.attach(new_fragment);              // <- this adds the fragment at the end
    ft.detach(old_fragment);              // <- this removes old fragment

    // This should be what you're looking for when adding to an Activity instead of a ViewPager
    ft.replace(view_id, new_fragment);    // <- this is supposed to replace the fragment attached to view_id

    // Or if the replace does not work, this might work:
    ft.detach(old_fragment);
    ft.add(view_id, new_fragment);

    // Not to be forgotten: ;)
    ft.commit();

The above code might need some adjustments, maybe only require the replace call to effectively work?

If the replace call fails, you can still detach all fragments and re-attach them in the order desired.

Upvotes: 0

Brian Cooley
Brian Cooley

Reputation: 11662

If your Fragment is created from a layout file, you cannot replace it at runtime. You can only successfully replace Fragments you added programmatically. See Android: can't replace one fragment with another

Upvotes: 0

Nhat Nam NGUYEN
Nhat Nam NGUYEN

Reputation: 1272

Do you try:

fragmentTransaction.remove(yourframent);

and then:

fragmentTransaction.add(yournewfragment);

Upvotes: 1

Related Questions