在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 ,就要謹慎一些了。