我正在使用ViewPager
并在其中显示许多不同的Fragments
,不仅在内容中,而且它们也使用不同的类。要显示的列表应该动态更改,即使我设法交换项目并向适配器添加新项目(并调用notifyDataSetChanged
),如果我尝试更改下一项目,它仍然会在使用时滑动到它mPager.setCurrentItem(mPager.getCurrentItem() + 1);
我只是在当前项和当前项之间添加一个新的Fragment
,它在适配器中正确显示但是由于下一个已经预加载,因此适配器中的getItem
不是甚至叫。
是否有另一种方法“强于”notifyDataSetChanged
告诉我的ViewPager
它应该再次获得下一个项目?
代码样本:
我的FragmentPagerAdapter
中的添加和获取项目方法(仅样本,而不是实际代码)
public void add(@NonNull Integer fragmentIndex) {
mFragmentOrder.add(fragmentIndex);
notifyDataSetChanged();
}
@Override
public Fragment getItem(int position) {
int selectedFragment = mFragmentOrder(position);
Fragment fragment;
switch (selectedFragment) {
case 1:
fragment = new FragmentA();
break;
case 2:
fragment = new FragmentB();
break;
case 3:
fragment = new FragmentC();
break;
default:
fragment = new FragmentD();
break;
}
return fragment;
}
这是用于转到下一个项目的功能(我不允许滑动)
public void goToNext() {
mPager.setCurrentItem(mPager.getCurrentItem() + 1);
}
编辑:
编辑1:我之前尝试使用FragmentStatePagerAdapter
并将OffscreenPageLimit
设置为0,但无济于事。
编辑2:[解决方案]使用FragmentStatePagerAdapter
AND覆盖getItemPosition
函数返回POSITION_NONE
或在适当情况下的索引解决了问题。出于某种原因,即使在实施了此功能的正确版本之后,正常的FragmentPagerAdapter
仍然提供了错误的Fragment
。
答案 0 :(得分:1)
默认情况下,FragmentPagerAdapter
会假定其项目的数量和位置保持不变。因此,如果要引入动态,则必须通过在继承的适配器类中实现getItemPosition(Object object)
方法来自行提供。一个非常基本(但效率不高)的实现是:
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
每当父视图确定其子视图(项)之一的位置是否已更改时,此代码将强制重新创建片段。如果您想在不必要时避免重新创建,则必须在方法中包含一些逻辑。像这样:
@Override
public int getItemPosition (Object object) {
if (fragmentOrder.indexOf(object) == -1) {
return POSITION_NONE;
} else {
return index;
}
}
最后,通过向片段添加onDestroyView
方法并使您正在使用的视图无效来注意可能的内存泄漏。
Here是对这两个PagerAdapter
s。