FragmentPagerAdapter不删除项目(片段)正确片段、正确、项目、FragmentPagerAdapter

2023-09-04 08:02:16 作者:倚梅看雪

我已经实现了FragmentPagerAdapter和并使用列表保存为我的ViewPager显示所有片段。上的addItem()我只需添加一个实例化的片段,然后调用notifyDataSetChanged()。我不知道这是否必要。

I have implemented the FragmentPagerAdapter and and using a List to hold all fragments for my ViewPager to display. on addItem() I simply add an instantiated Fragment and then call notifyDataSetChanged(). I am not sure if this is necessary or not.

我的问题简单地... 首先片段1

My problem simply... start with fragment 1

[Fragment 1] 

添加新的片段2

add new Fragment 2

[Fragment 1] [Fragment 2]

删除片段2

remove Fragment 2

[Fragment 1]

添加新的片段3

add new Fragment 3

[Fragment 1] [Fragment 2]

在添加新片段的一切似乎很大。有一次,我删除的片段,然后添加一个新实例化的片段旧的片段仍显示。当我去一个.getClass.getName()这是给我的片段3的名字,但是我仍然看到片段2

When adding new fragments everything seems great. Once I remove a fragment and then add a newly instantiated fragment the old fragment is still displayed. When i go a .getClass.getName() it is giving me Fragment 3's name however I still see Fragment 2.

我相信这可能是一个问题instantiateItem或等,但我认为适配器来处理我们。任何建议将是巨大的。

I believe this might be an issue with instantiateItem or such but I thought the adapter was to handle that for us. any suggestions would be great.

适配器code ...

adapter code...

public class MyPagerAdapter extends FragmentPagerAdapter {
public final ArrayList<Fragment> screens2 = new ArrayList<Fragment>();


private Context context;

public MyPagerAdapter(FragmentManager fm, Context context) {
    super(fm);
    this.context = context;
}

public void removeType(String name){
    for(Fragment f: screens2){
        if(f.getClass().getName().contains(name)){ screens2.remove(f); return; }
    }
    this.notifyDataSetChanged();
}

public boolean addSt(String tag, Class<?> clss, Bundle args){
    if(clss==null) return false;
    if(!clss.getName().contains("St")) return false; 
    if(!args.containsKey("cId")) return false;
    boolean has = false;
    boolean hasAlready = false;
    for(Fragment tab: screens2){
        if(tab.getClass().getName().contains("St")){
            has = true;
            if(tab.getArguments().containsKey("cId"))
                if(tab.getArguments().getLong("cId") == args.getLong("cId")){
                    hasAlready = true;
                }
            if(!hasAlready){
                // exists but is different so replace
                screens2.remove(tab);
                this.addScreen(tag, clss, args, C.PAGE_ST);
                // if returned true then it notifies dataset
                return true;
            }
        }
        hasAlready = false;
    }

    if(!has){ 
        // no st yet exist in adapter
        this.addScreen(tag, clss, args, C.PAGE_ST);
        return true;
    }

    return false;
}

public boolean removeCCreate(){
    this.removeType("Create");  
    return false;
}

@Override
public int getItemPosition(Object object) {

   return POSITION_NONE; //To make notifyDataSetChanged() do something
  }

public void addCCreate(){
    this.removeCCreate();
    Log.w("addding c", " ");
    this.addScreen("Create C",  CreateCFragment.class, null, C.PAGE_CREATE_C);
}

public void addScreen(String tag, Class<?> clss, Bundle args, int type){
    if(clss!=null){
        screens2.add(Fragment.instantiate(context, clss.getName(), args));
    }
}

@Override
public int getCount() {
    return screens2.size();
}


@Override
public Fragment getItem(int position) {
    return screens2.get(position); 
}

}

我实现了code使用确​​定片段类型,但是我严格地写了这code测试功能的一些贫民窟的意思。任何帮助或想法将是巨大的,因为它似乎没有多少人涉足FragmentPagerAdapters的世界。

I realize the code uses some "ghetto" means of determining the fragment type however I wrote this code strictly for testing functionality. Any help or ideas would be great as it seems that not many people ventured into the world of FragmentPagerAdapters.

推荐答案

我有同样的问题,我的解决方案是overring方法destroyItem如下。

I got same problem,and my solution was overring the method "destroyItem" as following.

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    FragmentManager manager = ((Fragment)object).getFragmentManager();
    FragmentTransaction trans = manager.beginTransaction();
    trans.remove((Fragment)object);
    trans.commit();
}

这是我的工作,没有任何人有另一种解决方案?

It's work for me,does anybody have another solutions?

更新:

我发现那些code制成片段删除不必要的,所以我加了一个条件,以避免它。

I found those code made Fragment removed unnecessary,so I added a condition to avoid it.

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    if (position >= getCount()) {
        FragmentManager manager = ((Fragment) object).getFragmentManager();
        FragmentTransaction trans = manager.beginTransaction();
        trans.remove((Fragment) object);
        trans.commit();
    }
}