美文网首页
ViewPager中调用notifyDataSetChanged

ViewPager中调用notifyDataSetChanged

作者: 山岭巨人郭敬明 | 来源:发表于2017-07-07 13:45 被阅读0次

    最基本的方法:

    针对于child view比较简单的情况(例如仅有TextView、ImageView等,没有ListView等展示数据的情况),可以在自己的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方法销毁,并且重新生成,加大系统开销,并在一些复杂情况下导致逻辑问题。特别是对于 只是希望更新child view内容的时候,造成了完全不必要的开销。

    更有效地方法:

    ViewPger在调用notifyDataSetChanged()时,会循环调用PagerAdapter中的getItemPosition()方法,遍历每一个pager。

    我们在instantiateItem()中通过setTag()的方式,记住每个pager页。在getItemPosition()中,获取object的getTag(),如果要换的页面的下标等于这个tag,返回POSITION_NONE;否则,返回 POSITION_UNCHANGED。

    这个方法返回 POSITION_NONE; ,表示这个页换了,会调用destroyItem()方法删除,再调用instantiateItem()方法,创建。
    返回 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时,Fragment的onDestroy方法和onDetach方法都被调用到。
    当Fragment重新被add时,Fragment的生命周期全部重新调用,但是savedInstanceState参数保留着之前存储的数据。

    相关文章

      网友评论

          本文标题:ViewPager中调用notifyDataSetChanged

          本文链接:https://www.haomeiwen.com/subject/ciilhxtx.html