2012-09-25 104 views
92

我无法在FragmentPagerAdapter中重复使用片段。使用destroyItem()方法,它正在删除片段,但仍然没有再次调用getItem()..只有2-3图像,所以我现在用FragmentPagerAdapter相反FragmentStatePagerAdapter的..FragmentPagerAdapter getItem不叫

public class ExamplePagerAdapter extends FragmentPagerAdapter { 

    ArrayList <String> urls; 
    int size = 0; 
    public ExamplePagerAdapter(FragmentManager fm, ArrayList <String> res) { 
     super(fm); 
     urls = res; 
     size = urls.size(); 
    } 

    @Override 
    public int getCount() { 
     if (urls == null) { 
      return 0; 
     } else { 
      return size; 
     } 

    } 

    @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(); 
    } 

    @Override 
    public Fragment getItem(int position) { 

     Fragment fragment = new FloorPlanFragment(); 
     Bundle b = new Bundle(); 
     b.putInt("p", position); 
     b.putString("image", urls.get(position)); 
     Log.i("image", "" + urls.get(position)); 
     fragment.setArguments(b); 
     return fragment; 
    } 
} 

并在FragmentActivity,

pager.setAdapter(new ExamplePagerAdapter(getSupportFragmentManager(), res2)); 
+2

是否有一个特殊的原因,你覆盖'destroyItem()'?这没有必要。 – CommonsWare

+0

重新初始化使用FragmentStatePagerAdapter 也可以调用,当你覆盖它 super.destroyItem(容器,位置,对象); – faiziii

回答

249

KISS答:

简单使用FragmentStatePagerAdapter inste广告FragmentPagerAdapter

我得到了答案。首先我想删除这个问题,因为我正在做一个非常愚蠢的错误,但这个答案将有助于面临同样问题的人,而不是FragmentPagerAdapter,使用FragmentStatePagerAdapter

由于@BlackHatSamurai在评论中提到:

这部作品的原因是因为FragmentStatePagerAdapter破坏 为未使用的片段。 FragmentPagerAdapter没有。

+6

谢谢,你救了我。 –

+1

谢谢。真的帮我出去了 –

+0

我想知道为什么呢? –

2

有两种不同的情况:1。 )您有相同的布局,每寻呼机: 在这种情况下,它会更好,如果你通过PagerAdapter扩展您的自定义适配器 并返回一个布局。

2)你必须为每一个寻呼机不同的布局: 在这种情况下,它会更好,如果你通过FragmentStatePagerAdapter扩展您的自定义适配器 并为每寻呼机返回不同fragmets。

116

使用FragmentStatePagerAdapter没有完全解决我的问题,这是一个类似的问题,其中onCreateView未被视图寻呼机中的子片段调用。我实际上是将我的FragmentPagerAdapter嵌套在另一个Fragment之内,因此FragmentManager在所有这些中共享,因此保留了旧片段的实例。解决的办法是将getChildFragmentManager的一个实例提供给我的主机片段中的FragmentPagerAdapter的构造函数。喜欢的东西...

FragmentPagerAdapter adapter = new FragmentPagerAdapter(getChildFragmentManager()); 

getChildFragmentManager()方法是通过片段访问,这个工作对我来说,因为它返回一个私人FragmentManager该片断专门为这是需要嵌套的片段的情况。我希望这可以帮助那些可能遇到同样问题的人!

  • 但是请记住使用getChildFragmentManager()您的最低API版本至少要包含17 (4.2),所以这可能会在你扔的齿轮扳手。当然,如果你使用支持库v4的片段,你应该没问题。
+18

这是正确的答案。问题在于嵌套在其他片段中的片段应该使用getChildrenFragmentManager()而不是getFragmentManager()。 – shihpeng

+0

非常感谢,我永远花了我的时间找到这个答案! – Shpongoloid

+0

我同意@shihpeng。这应该是正确的答案。 –

0

我发现,设置在标签布局的监听器停止这个被称为,可能是因为他们只有空间,一个监听器tabLayout.setOnTabSelectedListener,而不是侦听器的数组。

2

我做了@kanika和@ Jraco11发布的内容,但我仍然遇到了问题。

所以,很多的变化后,我发现一个很适合我,并加入到我的FragmentPagerAdapter下一个代码:

@Override 
    public int getItemPosition(Object object) { 
     return POSITION_NONE; 
    } 

根据我读,getItemPosition用来通知ViewPager是否刷新一个项目,并避免更新如果可见位置上的项目没有改变。

0

覆盖long getItemId (int position)

FragmentPagerAdapter缓存它创建使用getItem片段。我正面临同样的问题 - 即使拨打电话notifyDataSetChanged()getItem未被调用。

这实际上是一个功能,而不是一个错误。您需要覆盖getItemId,以便您可以正确重复使用您的片段。由于您正在移除碎片,因此您的位置正在改变。如在该文档中提到:

long getItemId (int position)

返回在给定位置处的项目的唯一标识符。

默认实现返回给定位置。 如果项目的位置可以更改,子类应该重写此方法。

只要为每个片段提供一个唯一的ID,就完成了。

使用FragementStatePagerAdapter或返回POSITION_NONEint getItemPosition (Object object)是错误的。你不会得到任何缓存。

相关问题