Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android -- 處理ViewPager的notifyDataSetChanged無刷新

Android -- 處理ViewPager的notifyDataSetChanged無刷新

編輯:關於Android編程

Viewpager在調用notifyDataSetChanged()時,界面無刷新,它確實影響我們功能的實現了。可能選擇為Viewpager重新設置一遍適配器adapter,達到刷新的目的。但是這種方法在大多數情況下,是有問題的。   查看方法   super.notifyDataSetChanged()調用的是PagerAdapter.notifyDataSetChanged()     /**      * This method should be called by the application if the data backing this adapter has changed      * and associated views should update.      */     public void notifyDataSetChanged() {         mObservable.notifyChanged();     }   注釋裡說到,當附加在適配器上的數據發生變化時,應該調用該方法刷新數據。該方法調用了一個mObservable .notifyChanged();   我們繼續跟進這個方法,進入DataSetObservable類中,發現這樣一段代碼:   /**      * Invokes {@link DataSetObserver#onChanged} on each observer.      * Called when the contents of the data set have changed.  The recipient      * will obtain the new contents the next time it queries the data set.      */     public void notifyChanged() {         synchronized(mObservers ) {             // since onChanged() is implemented by the app, it could do anything, including             // removing itself from {@link mObservers} - and that could cause problems if             // an iterator is used on the ArrayList {@link mObservers}.             // to avoid such problems, just march thru the list in the reverse order.             for (int i = mObservers .size() - 1; i >= 0; i--) {                 mObservers.get(i).onChanged();             }         }     }   這都不是重點,重點我們來看這個mObservers的類型是一個抽象類DataSetObserver,裡面只有兩個未實現的方法,都有誰使用了這個抽象類呢,其中我們發現了Viewpager的身影。進入viewpager,我們終於找到了viewpager中控制數據變更的重點方法dataSetChanged ,這個方法如下:     void dataSetChanged () {         // This method only gets called if our observer is attached, so mAdapter is non-null.           boolean needPopulate = mItems .size() < mOffscreenPageLimit * 2 + 1 &&                 mItems.size() < mAdapter.getCount();         int newCurrItem = mCurItem ;           boolean isUpdating = false;         for (int i = 0; i < mItems.size(); i++) {             final ItemInfo ii = mItems .get(i);             final int newPos = mAdapter.getItemPosition(ii.object );               if (newPos == PagerAdapter.POSITION_UNCHANGED ) {                 continue;             }               if (newPos == PagerAdapter.POSITION_NONE) {                 mItems.remove(i);                 i--;                   if (!isUpdating) {                     mAdapter.startUpdate( this);                     isUpdating = true;                 }                   mAdapter.destroyItem( this, ii.position , ii.object);                 needPopulate = true;                   if (mCurItem == ii.position ) {                     // Keep the current item in the valid range                     newCurrItem = Math. max(0, Math.min(mCurItem, mAdapter.getCount() - 1));                     needPopulate = true;                 }                 continue;             }               if (ii.position != newPos) {                 if (ii.position == mCurItem ) {                     // Our current item changed position. Follow it.                     newCurrItem = newPos;                 }                   ii. position = newPos;                 needPopulate = true;             }         }           if (isUpdating) {             mAdapter.finishUpdate( this);         }           Collections. sort(mItems, COMPARATOR);           if (needPopulate) {             // Reset our known page widths; populate will recompute them.             final int childCount = getChildCount();             for (int i = 0; i < childCount; i++) {                 final View child = getChildAt(i);                 final LayoutParams lp = (LayoutParams) child.getLayoutParams();                 if (!lp.isDecor ) {                     lp. widthFactor = 0.f;                 }             }               setCurrentItemInternal(newCurrItem, false, true);             requestLayout();         }     }   重點看這樣一行代碼:   final int newPos = mAdapter.getItemPosition(ii.object );      if (newPos == PagerAdapter.POSITION_UNCHANGED ) {          continue ;    }   Called when the host view is attempting to determine if an item’s position has changed. Returns POSITION_UNCHANGED if the position of the given item has not changed orPOSITION_NONE if the item is no longer present in the adapter.   The default implementation assumes that items will never change position and always returnsPOSITION_UNCHANGED.   意思是如果item的位置如果沒有發生變化,則返回POSITION_UNCHANGED。如果返回了POSITION_NONE,表示該位置的item已經不存在了。默認的實現是假設item的位置永遠不會發生變化,而返回POSITION_UNCHANGED   解決方案   所以我們可以嘗試著修改適配器的寫法,覆蓋getItemPosition()方法,當調用notifyDataSetChanged時,讓getItemPosition方法人為的返回POSITION_NONE,從而達到強迫viewpager重繪所有item的目的。     class SearchAdapter extends PagerAdapter {           private int mChildCount = 0;        @Override      public void notifyDataSetChanged() {                     mChildCount = getCount();            super.notifyDataSetChanged();      }        @Override      public int getItemPosition(Object object)   {                      if ( mChildCount > 0) {            mChildCount --;            return POSITION_NONE;            }            return super.getItemPosition(object);      }  
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved