更新ViewPager裡面某一個View的內容

转载地址:http://lovekongnan.blog.163.com/blog/static/9604192320121014172286/


在stackoverflow有一篇文章的問題是”ViewPager PagerAdapter not updating the View“,在觀看這篇文章時,剛好我的app應用也有類似的問題,就是該如果更新ViewPager裡某一個View的內容,而不是全部砍掉重建。後來在欣賞外國佬的回答後,有位大大rui.araujo提出一個十分容易解決的方式,就是改寫getItemPosition()

Override getItemPosition in your PagerAdapter like this:

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

This way, when you call notifyDataSetChanged(), the view pager will remove all views and reload them all. As so the reload effect is obtained.

讓每次呼叫PagerAdapter時,都會被誤判會POSITION_NONE並重新建置所有View。如此一來會造成效能上很大的問題,而且邏輯上也是不太正確。我一開始也是使用這方法來解決我碰到的問題,但後來另一位大大alvarolb為此種錯誤的解法方式做了一些解釋,當中提到為何改寫getItemPosition為永遠回POSITION_NONE是錯誤的邏輯,原文如下:

The notifyDataSetChanged() method on the PagerAdapter will only notify the ViewPager that the underlying pages have changed. For example, if you have create/deleted dynamically pages (adding or removing items from your list) the ViewPager should take care about that. In this case i think that the ViewPager determines if a new view should be deleted or instantiated using the getItemPosition() and getCount() methods.

就連官方SDK文件也說明了ViewPager Adapter notifyDataSetChanged的用意為

PagerAdapter supports data set changes. Data set changes must occur on the main thread and must end with a call to notifyDataSetChanged()similar to AdapterView adapters derived from BaseAdapter. A data set change may involve pages being added, removed, or changing position. The ViewPager will keep the current page active provided the adapter implements the method getItemPosition(Object).

原文看完後,大概是說明Adapter會自動控管View Pager每一頁(Item)的狀態,而notifyDataSetChanged()是用在當View Pager要新增一頁、刪除一頁或改變各個頁面的排列的時候。所以ViewPager Adapter的notifyDataSetChanged自然就不適用於只要更新View Pager裡面某個View的內容的需求啦。所以alvarolb也針對此向需求做了一翻解釋

My approach is to use the setTag() method for any instantiated view in the instantiateItem() method. So when you want to change the data or invalidate the view that you need, you can call the findViewWithTag() method on the viewPager to retrieve the previously instantiated view and modify/use it as you want without having to delete create any new view each time you want to update some value.

關鍵點就是在instantiateItem時,將有需要在後續進行內容更新的view來setTag(),並且在需要更新的時候,使用viewpager的findViewWithTag(),來找到要更新的View並進行更新。講了這 長的文章,還是來用程式碼來說明會來的直覺一點,我有省略很多細節,主要把精隨分享給大家。

	@Override     
	public 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 */    
	}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值