我已经实现了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();
}
}