今天工作中遇到了這個糾結的問題,在ViewPager中調用PagerAdapter.notifyDataSetChanged()方法,好像沒有任何作用,相應的View也沒有更新數據,根據官方API是這樣解釋的:大概是說明Adapter會自動管轄ViewPager每一頁(Item)的狀態,而notifyDataSetChanged()是用在當Vie Pager要新增一頁、刪除一頁或改變各個頁面的排列的時候。所以ViewPager Adapter的notifyDataSetChanged自然就不適用於只更新View Pager裏面某個View的內容的需求。對此查閱後終於得到了一個相對穩定的解決方案,Mark一下。
一、一種簡單的解決方案
這種方案我相信只要是對ViewPager數據更新問題有研究的都會了解,即覆蓋PagerAdapter中的getItemPosition()方法,這種方案雖然簡單,但是因爲這種方法是讓每次呼叫PagerAdapter時,都會遍歷childView,通過getItemPosition()方法返回Item位置失去的參數,這樣PagerAdapter誤認爲Item失去位置,因而重新建立所有childView,這樣做來,開銷過大,而且由於佔用了getItemPosition()方法,也不適用於複雜的View界面,只適合TextView,EditText等簡單的View。
覆蓋代碼:
public int getItemPosition(Object object){
return POSITION_NONE;
}
二、PagerAdapter的工作機制
這裏所說的工作機制,嚴格意義上講就是PagerAdapter的執行順序,也是Leo8573通過調試自己理解的。
PagerAdapter作爲ViewPager的適配器,無論ViewPager有多少頁,PagerAdapter在初始化時也只初始化開始的2個View,即調用2次instantiateItem方法。而接下來每當ViewPager滑動時,PagerAdapter都會調用destroyItem方法將距離該頁2個步幅以上的那個View銷燬,以此保證PagerAdapter最多隻管轄3個View,且當前View是3箇中的中間一個,如果當前View缺少兩邊的View,那麼就instantiateItem,如裏有超過2個步幅的就destroyItem。
簡易圖示:
*
------+---+---+---+------
... 0 | 1 | 2 | 3 | 4 ...
------+---+---+---+------
當前View爲2號View,所以PagerAdapter管轄1、2、3三個View,接下來向左滑動-->
*
------+---+---+---+------
... 1 | 2 | 3 | 4 | 5 ...
------+---+---+---+------
滑動後,當前View變爲3號View,PagerAdapter會destroyItem 0號View,instantiateItem 5號View,所以PagerAdapter管轄2、3、4三個View
大概就是這樣,各位領會精神吧,Leo8573文字表達能力還是有點差。
三、較通用的解決方案
所謂通用的方案,即對於任何ViewPager中的View都可以進行數據更新,具體的方法是每當Adapter調用instantiateItem時,運用View.setTag方法將該View標識。當需要更新這個View的數據時,通過調用ViewPager.findViewWithTag方法找到相應的View,然後更新View中的數據。不能空說不練,最後給上關鍵代碼,領會精神。
代碼示例:
@Overridepublic Object instantiateItem(ViewGroup container, int position) {
View view = null;
view = mInflater.inflate(R.layout.record_list_layout, null);
TextView tvRecord = (TextView) view.findViewById(R.id.tv_record);
String key = "tvRecord" + position;
// 關鍵點,針對要更新的View來設定Tag,主要是在後續使用ViewPager.findViewWithTag()時,可以找到要更新的View
tvRecord.setTag(key);
container.addView(view)
return view;}
// 在後續的應用當中,如果要開始更新View Pager當中某個View的內容時,需要進行下列動作
TextView tvRecord = myViewPager.findViewWithTag("tvRecord1");
// 假設要更新第2頁的TextView
// 進行內容更新
if (tvRecord != null ) { tvRecord.setText("update");
} /* end of if */
}
上是自己查閱信息後的小體會,不對的地方請各位朋友指正,Leo8573鞠躬下臺。