从由FragmentStatePagerAdapter填充的ViewPager中删除所有片段

8

我有一个ViewPager,使用FragmentStatePagerAdapter填充其中的碎片(表示来自arrayListOfObjects的对象)。 一切正常:

            mMyFragmentPagerAdapter = new fragmentAdapter(getSupportFragmentManager(),orientation
            ,rePopulatedfireInfoList);
        mPager = (ViewPager)findViewById(R.id.fireInfoFragment_container);
        initButton();
        setTab();
        mPager.setAdapter(mMyFragmentPagerAdapter); 

片段适配器扩展了 FragmentStatePagerAdapter。

从主活动中,我启动一个对话框主题的活动;用户可以添加一个新的喜爱位置,创建一个修改主活动传递的对象数组的新对象。 下面是启动对话框活动的代码;所有功能正常:

        Intent locationIntent = new Intent(afisController.this, locationActivity.class);
    locationIntent.putExtra("firesList", new fireInfoListWrapper(arrayListOfObjects));
    startActivityForResult(locationIntent,1);

浮动活动将对象添加到对象列表。

在主要活动的onActivityResult中,我将接收到的arrayListOfObjects与发送的arrayListOfObjects进行比较;如果不同,我希望完全删除viewPager的内容,并使用新的arrayListOfObjects重新创建它。这是onActivityResults:

     protected void onActivityResult(int requestCode, int resultCode,
            Intent data) {
 Toast.makeText(this, "Activity Results fired..." , 1500 ).show();
            if ((resultCode == 0) && (data != null)) { 
                Log.i("onActvityResult", "Inside resultCode check");   
                Bundle b = data.getExtras();
                if(b != null){
                    Log.i("onActvityResult", "not null");
                    returnedFireInfoList = (ArrayList<fireInfo>) data.getSerializableExtra("firesListResult"); 
                    Log.i("onActvityResult", "results Size: "+returnedFireInfoList.size());
                    if(returnedFireInfoList.size()>0){
                        Log.i("onActvityResult", "locationName: "+returnedFireInfoList.get(0).getLocationName());
                        //compare returnedFireInfoList and rePopulatedfireInfoList, if different; 
                        //add difference to rePopulatedfireInfoList and write back to file.
                        updateFireInfos(returnedFireInfoList, rePopulatedfireInfoList);
        if(returnedFireInfoList.size()!=rePopulatedfireInfoList.size()){
mMyFragmentPagerAdapter1 = new fragmentAdapter(getSupportFragmentManager(),orientation
                    ,returnedFireInfoList);
            mPager = (ViewPager)findViewById(R.id.fireInfoFragment_container); 
            Log.i("updateFireInfos", "fragmentsCount is"+mPager.getCurrentItem());
            fireInfoFragment fragment = 
                      (fireInfoFragment) getSupportFragmentManager().findFragmentById(R.id.fireInfoFragment_container);
//This is where the problem is, I don't want to remember what was already on the viewPager //called mPager before.
           //   mPager.removeAllViews();
            //mPager.setAdapter(null);
            mMyFragmentPagerAdapter1.notifyDataSetChanged();            
            mPager.setAdapter(mMyFragmentPagerAdapter1);               mMyFragmentPagerAdapter1.notifyDataSetChanged();                     
                    }                   
                }
            }        

这是FragmentStateAdapter的代码:
public class fragmentAdapter extends FragmentStatePagerAdapter {

private FragmentManager fragmentManager;
 private FragmentTransaction mCurTransaction = null;
 private ArrayList<Fragment.SavedState> mSavedState = new ArrayList<Fragment.SavedState>();
 private ArrayList<Fragment> mFragments = new ArrayList<Fragment>();
 private Fragment mCurrentPrimaryItem = null;



public void restoreState(Parcelable state, ClassLoader loader) {
    //Need to only delete info from marked fragments (theoned that are stored on orientationchange
    //Currently redoing the entire call; resulting in delay due to server call
    //if(isLastOrientationPortrait != isPortrait){
    if(state != null){
        Bundle bundle1 = (Bundle) state;
        bundle1.setClassLoader(loader);
        Iterable<String> keys = bundle1.keySet();
        Log.i("restoreState", "containsKey FragmentStatePagerAdapter: "+keys);
        //android.support.v4.app.FragmentManager fragmentManager= fragmentAdapter.this.fragmentManager;
        android.support.v4.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 
        //if (fragmentTransaction == null) {
        //  Log.i("restoreState", "fragmentTransactionTest");

            fragmentTransaction = fragmentManager.beginTransaction();
       // }
        for (String key : keys) {
            if (key.startsWith("f")) {
                Fragment f = fragmentManager.getFragment(bundle1,
                        key);
                fragmentTransaction.remove(f);
                fragmentTransaction.commit();
            }
            }
        }
    //}       
    }


@Override
public int getItemPosition(Object object) {
    // TODO Auto-generated method stub
    //return super.getItemPosition(object);
    return fragmentAdapter.POSITION_NONE;
}


public fragmentAdapter(android.support.v4.app.FragmentManager fragmentManager,String orientation,
         ArrayList<fireInfo> fireInfoList) {
     super(fragmentManager);
     this.orientation = orientation;
     this.fireInfoList = fireInfoList;
     this.numItems = fireInfoList.size();
     this.fragmentManager=fragmentManager;
 }
 ArrayList<fireInfo> fireInfoList;
 String orientation;
 int numItems;


@Override
 public int getCount() {
     Log.i("numItems", "is: "+fireInfoList.size());
     return numItems;
 }

@Override
public Fragment getItem(int arg0) {
    Log.i("fragmentAdapterIndex", "is: "+arg0);
    return fireInfoFragment.newInstance(orientation, fireInfoList.get(arg0));
}    

}

问题: 但是在我启动startActivityForResult之前,新的ArrayListOfObjects被添加到旧的ArrayListOfObjects旁边。

我该如何强制viewPager忘记它旧的内容?基本上使用我的fragmentStateAdapter重置viewPager适配器以使用这个新的ArrayListOfObjects?

2个回答

53

我猜问题在于你的适配器所使用的 FragmentManager 仍然存在旧碎片。如果是这种情况,你只需要从片段管理器中删除所有旧碎片。

因此,在你的适配器构造函数中执行以下代码即可:

public fragmentAdapter(FragmentManager fragmentManager, String orientation, ArrayList<fireInfo> list) {
    super(fragmentManager);
    if (fragmentManager.getFragments() != null) {
        fragmentManager.getFragments().clear();
    }
    //... your other code here
}

这行代码是不必要的:

mMyFragmentPagerAdapter1.notifyDataSetChanged();     

编辑:使用FragmentTransaction删除片段可能更加准确:

    List<Fragment> fragments = fragmentManager.getFragments();
    if (fragments != null) {
        FragmentTransaction ft = fragmentManager.beginTransaction();
        for (Fragment f : fragments) {
            //You can perform additional check to remove some (not all) fragments:
            if (f instanceof AddedByCurrentPagerAdapterFragment) { 
                ft.remove(f);
            }
        }
        ft.commitAllowingStateLoss();
    }

执行FragmentTransaction的操作需要一些时间(异步执行)。


1
当您想要保留由同一FragmentManager管理的其他片段,但仅想删除此FragmentPagerAdapter创建的片段时会发生什么? - mmathieum
@mmathieum 请查看编辑部分。 - Alex Semeniuk
fragmentManager.getFragments() 不是一个公共函数: https://dev59.com/U1gQ5IYBdhLWcg3wkEtJ - tonisives
@appdeveloper27 直到最近我还在使用它。目前我不确定要用什么替代它。我的建议是使用旧版本的支持库,其中 getFragments() 方法仍然是公共的。 - Alex Semeniuk
这个不再起作用了。 - Michalsx
显示剩余2条评论

0
所有我需要做的就是重新分配FragmentStatePagerAdapter。
这已经在onActivityResult中呈现,但掩盖了正确的行为的是我的viewPager页面指示器,它会增加页面数量。例如,如果我在viewPager上有2个页面,并调用子活动,该子活动将在arrayListOfObjects中添加一个对象;viewPager页面指示器将显示我现在有2加三个页面(5)。
我必须在onActivityResult中重置viewPage指示器,以便它由浮动活动返回的新arrayListOfObjects来确定。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接