ViewPager中調用notifyDataSetChanged失效問題

最基本的方法:

針對于child view比較簡單的情況(例如僅有TextView、ImageView等,沒有ListView等展示數(shù)據(jù)的情況),可以在自己的Adapter中加入代碼:

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

這樣既可達到一般情況下要求的效果。

存在的問題:

這不是PagerAdapter中的Bug,通常情況下,調用 notifyDataSetChanged方法會讓ViewPager通過Adapter的getItemPosition方法查詢一遍所有child view,這種情況下,所有child view位置均為POSITION_NONE,表示所有的child view都不存在,ViewPager會調用destroyItem方法銷毀,并且重新生成,加大系統(tǒng)開銷,并在一些復雜情況下導致邏輯問題。特別是對于 只是希望更新child view內容的時候,造成了完全不必要的開銷。

更有效地方法:

ViewPger在調用notifyDataSetChanged()時,會循環(huán)調用PagerAdapter中的getItemPosition()方法,遍歷每一個pager。

我們在instantiateItem()中通過setTag()的方式,記住每個pager頁。在getItemPosition()中,獲取object的getTag(),如果要換的頁面的下標等于這個tag,返回POSITION_NONE;否則,返回 POSITION_UNCHANGED。

這個方法返回 POSITION_NONE; ,表示這個頁換了,會調用destroyItem()方法刪除,再調用instantiateItem()方法,創(chuàng)建。
返回 POSITION_UNCHANGED,表示沒換,什么也不做。

private List<View> mViewCache = new ArrayList<View>();  
private ViewPager viewPager;  
private int curUpdatePager;  
  
// 適配器  
class MyPagerAdapter extends PagerAdapter {  
  
  
    public void destroyItem(View arg0, int arg1, Object arg2) {  
        View view = (View)arg2;  
        ((ViewPager) arg0).removeView((View)arg2);  
    }  
  
  
    public void finishUpdate(View arg0) {  
    }  
  
  
    public int getCount() {  
        return mViewCache.size();  
    }  
  
  
    public Object instantiateItem(View arg0, int arg1) {  
        mViewCache.get(arg1).setTag(arg1);  
        ((ViewPager) arg0).addView(mViewCache.get(arg1));  
  
  
        return mViewCache.get(arg1);  
    }  
  
  
    public boolean isViewFromObject(View arg0, Object arg1) {  
        return arg0 == (arg1);  
    }  
  
  
    public void restoreState(Parcelable arg0, ClassLoader arg1) {  
    }  
  
  
    public Parcelable saveState() {  
        return null;  
    }  
  
  
    @Override  
    public void startUpdate(View arg0) {  
    }  
  
    @Override  
    public int getItemPosition(Object object) {  
        View view = (View)object;  
        if(curUpdatePager == (Integer)view.getTag()){  
            return POSITION_NONE;    
        }else{  
            return POSITION_UNCHANGED;  
        }  
        // return super.getItemPosition(object);  
    }  
}  
  
/** 
 * 更換pager的方法 
 * @param view   新的pager 
 * @param index  第幾頁 
 *  
 * 示例:updateViewPagerItem(fragment2_parentctrl_changepwd,1); 
 */  
private void updateViewPagerItem(View view,int index){  
    curUpdatePager = index;  
    mViewCache.remove(index);  
    mViewCache.add(index, view);  
    viewPager.getAdapter().notifyDataSetChanged();  
    // findViewById(getResources().getIdentifier("sysset_button"+(index+1), "id", "com.jzbyapp.suzhou")).requestFocus();  
}  

Fragment在FragmentStatePagerAdapter類的destroyItem方法中被remove時,F(xiàn)ragment的onDestroy方法和onDetach方法都被調用到。
當Fragment重新被add時,F(xiàn)ragment的生命周期全部重新調用,但是savedInstanceState參數(shù)保留著之前存儲的數(shù)據(jù)。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容