Reputation: 681
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
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
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
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
Reputation: 1272
Do you try:
fragmentTransaction.remove(yourframent);
and then:
fragmentTransaction.add(yournewfragment);
Upvotes: 1