在listview中,如果我们要更新数据直接调用notifyDataSetChanged()即可,但是在Viewpager嵌套fragment时,导致直接调用并不会生效。具体原因可以参考这篇,作者分析的非常透彻,而且给出了FragmentPagerAdapter 更新数据的解决方案。
但是正如作者在文中所说的一样,少量页面应该选择使用FragmentPagerAdapter ,但是页面较多时,还是应该使用FragmentStatePagerAdapter,而在FragmentStatePagerAdapter中只能通过强制销毁页面并重建的方式更新数据么?
最近在做一个项目,viewpager的页面是不固定的,理论上可以是非常多的,这时候就要使用FragmentStatePagerAdapter来优化体验了,但是更新数据时,大多是只是更新一些页面上一些空间的显示,直接调用notifyDataSetChanged,重建页面有点太浪费了,于是我就想了一个简单的解决方案,在这里和大家分享一下,大家有更好的方法话可以提出来,共同学习。
基本思路就是在更新的时候,拿到当前页面以及前一个和后一个页面的fragment,然后调用fragment中我们的某些更新方法,进行页面的刷新。
这样就不用notifyDataSetChanged(),直接更新控件即可。
获取当前页面的fragment(在FragmentStatePagerAdapter中添加):
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
currentFragment = (BaseFragment) object;
super.setPrimaryItem(container, position, object);
}
public BaseFragment getCurrentFragment(){
return currentFragment;
}
同时在创建fragment时,将当前页面的位置作为参数保存进去:
@Override
public BaseFragment getItem(int position) {
LogUtils.d("getItem"+position);
return FragmentFactory.getInstance().createFragment(position);
}
在Activity中刷新时:
private void refreshPage(){
int currentPos = adapter.getCurrentFragment().getCurrentPosition();
int previousPos = currentPos - 1;
int nextPos = currentPos + 1;
LogUtils.d("currentPos:"+currentPos+" previousPos:"+previousPos+" nextPos:"+nextPos);
if(previousPos != -1){
adapter.getItem(previousPos).refreshData();
}
adapter.getItem(currentPos).refreshData();
if(nextPos <= adapter.getCount() - 1){
adapter.getItem(nextPos).refreshData();
}
}
思路和方法都是很简单的,就是想办法获取到当前fragment实例,然后顺带刷新前一个和后一个页面(ViewPager会预加载这些页面)。当然,如果你认为就更新个数据,添加这么多代码很麻烦,直接修改getItemPosition():
@Override
public int getItemPosition(Object object) {
LogUtils.d("getItemPosition");
return PagerAdapter.POSITION_NONE;
}
在更新数据时,像listview一样直接调用notifyDataSetChanged()就可以了。但是,如果你是用的FragmentPagerAdapter ,就要谨慎一些了。