问题
I must be missing something but I cannot remove a fragment from my ViewPager
. I store the page titles in an ArrayList
:
Part of ViewPagerActivity.java
(which is a FragmentActivity
, the main activity):
public static ArrayList<String> mEntries = new ArrayList<String>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate( savedInstanceState );
setContentView( R.layout.main );
context=this;
mEntries.add(" 111");
mEntries.add(" 222");
mEntries.add(" 333");
mEntries.add(" 444");
mEntries.add(" 555");
mEntries.add(" 666");
List<String> fragments = new Vector<String>();
fragments.add(111.class.getName());
fragments.add(222.class.getName());
fragments.add(333.class.getName());
fragments.add(444.class.getName());
fragments.add(555.class.getName());
fragments.add(666.class.getName());
this.mPagerAdapter = new PagerAdapter1(super.getSupportFragmentManager(), fragments);
pager = (ViewPager)super.findViewById(R.id.viewpager);
pager.setAdapter(this.mPagerAdapter);
// ...
I have a fragment (111
) where I would like to remove the 555
fragment by clicking a button in 111
. (Since it starts with 0
, 555
is the 4th fragment).
Part of fragment111.java
(which is a Fragment
):
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ViewPagerActivity.mEntries.remove(5);
ViewPagerActivity.mPagerAdapter.removeX(5);
ViewPagerActivity.mPagerAdapter.removeX2(5);
ViewPagerActivity.pager.setAdapter( ViewPagerActivity.mPagerAdapter);
ViewPagerActivity.pager.getAdapter().notifyDataSetChanged();
}
});
I have the POSITION_NONE
thing that some people miss by overriding the getItemPosition()
method.
my adapter class:
public class PagerAdapter1 extends FragmentStatePagerAdapter {
private List<String> fragments;
private static final String TAG = "FragmentPagerAdapter";
private static final boolean DEBUG = true;
private Fragment mCurrentPrimaryItem = null;
private final FragmentManager mFragmentManager;
private FragmentTransaction mCurTransaction = null;
/**
* @param fm
* @param fragments2
*/
public PagerAdapter1(FragmentManager fm, List<String> fragments2) {
super(fm);
mFragmentManager=fm;
this.fragments = fragments2;
}
/* (non-Javadoc)
* @see android.support.v4.app.FragmentPagerAdapter#getItem(int)
*/
@Override
public Fragment getItem(int position) {
//return this.fragments.get(position);
return Fragment.instantiate(ViewPagerActivity.context, fragments.get(position));
}
/* (non-Javadoc)
* @see android.support.v4.view.PagerAdapter#getCount()
*/
@Override
public int getCount() {
return this.fragments.size();
}
/**
* Return the Fragment associated with a specified position.
*/
@Override
public void startUpdate(ViewGroup container) {
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
final long itemId = getItemId(position);
// Do we already have this fragment?
String name = makeFragmentName(container.getId(), itemId);
Fragment fragment = mFragmentManager.findFragmentByTag(name);
if (fragment != null) {
if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment);
mCurTransaction.attach(fragment);
} else {
fragment = getItem(position);
if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);
mCurTransaction.add(container.getId(), fragment,
makeFragmentName(container.getId(), itemId));
}
if (fragment != mCurrentPrimaryItem) {
fragment.setMenuVisibility(false);
fragment.setUserVisibleHint(false);
}
return fragment;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
if (DEBUG) Log.v(TAG, "Detaching item #" + getItemId(position) + ": f=" + object
+ " v=" + ((Fragment)object).getView());
mCurTransaction.detach((Fragment)object);
}
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
Fragment fragment = (Fragment)object;
if (fragment != mCurrentPrimaryItem) {
if (mCurrentPrimaryItem != null) {
mCurrentPrimaryItem.setMenuVisibility(false);
mCurrentPrimaryItem.setUserVisibleHint(false);
}
if (fragment != null) {
fragment.setMenuVisibility(true);
fragment.setUserVisibleHint(true);
}
mCurrentPrimaryItem = fragment;
}
}
@Override
public void finishUpdate(ViewGroup container) {
if (mCurTransaction != null) {
mCurTransaction.commitAllowingStateLoss();
mCurTransaction = null;
mFragmentManager.executePendingTransactions();
}
}
@Override
public boolean isViewFromObject(View view, Object object) {
return ((Fragment)object).getView() == view;
}
@Override
public Parcelable saveState() {
return null;
}
@Override
public void restoreState(Parcelable state, ClassLoader loader) {
}
/**
* Return a unique identifier for the item at the given position.
*
* <p>The default implementation returns the given position.
* Subclasses should override this method if the positions of items can change.</p>
*
* @param position Position within this adapter
* @return Unique identifier for the item at position
*/
public long getItemId(int position) {
return position;
}
private static String makeFragmentName(int viewId, long id) {
return "android:switcher:" + viewId + ":" + id;
}
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
public void removeX(int position){
fragments.remove(5);
}
public void removeX2(int position){
Fragment ff = getItem(position);
mFragmentManager.beginTransaction().remove(ff).commit();
notifyDataSetChanged();
}
}
I am using FragmentStatePagerAdapter
and the notifyDataSetChanged()
works well (I update state of a CheckBox
and I see it works). How can I remove this fragment from the ViewPager
?
Thanks in advance!
回答1:
The problem is the FragmentStatePagerAdapter, which reclaims the gone-from-view fragments. Even if you create a new one. Try using the FragmentPagerAdapter instead, which makes a fresh start on instantiating it.
回答2:
I had the same problem, the only solution I found was to set the adapter again after removing the fragment like this :
@Override
public void onClick(View v) {
ViewPagerActivity.mEntries.remove(4);
pager.setAdapter(mPagerAdapter);
}
UPDATE : YOU DON'T NEED TO SET THE ADAPTER AGAIN. Here some methods of my PagerAdapter, you need probably to do some modifications to use it as FragmentPagerAdapter
To remove views :
public static void deleteChildren(int pStart) {
List<ViewInfo> viewToRemove = new ArrayList<ViewInfo>();
for (int iView = pStart+1; iView < _views.size(); iView++) {
viewToRemove.add(_views.get(iView));
}
if (viewToRemove.size() != 0) {
_views.removeAll(viewToRemove);
}
}
@Override
public void destroyItem(View pView, int pIndex, Object pObject) {
((ViewPager) pView).removeView((View)pObject);
}
Override getItemPosition(Object pObject) :
@Override
public int getItemPosition(Object pObject) {
int pos = 0;
for (ViewInfo iView : _views) {
if (iView.mView == (View)pObject) {
break;
}
pos++;
}
return pos;
}
Refresh all views :
public static void refreshAdapterViewPager() {
_pagerAdapter.notifyDataSetChanged();
}
来源:https://stackoverflow.com/questions/15212309/cannot-remove-fragment-from-viewpager-why