Android ApiDemos示例解析(180):Views->Lists->13. Slow Adapter

對於一個長列表,如果每個列表項載入比較費時( 比如從網絡下載圖像),如果此時需要快速滾動列表,可以先給列表項使用一個替代名稱或是其它可以快速載入的項,當列表停止滾動時再載入實際的列表項,這樣可以大大提高列表的響應性能。

本例在ListView中顯示一個字符串數組來模擬一個費時的列表項載入(盡管顯示文字列表項實際上很快),當列表開始滾動或是快速飛行時,使用一個臨時數據來綁定列表項(如Loading …),而在列表停止滾動時,使用實際需要顯示的文字替換之前顯示的臨時數據。

看看自定義SlowAdapter的getView 的實現:

[java] 
public View getView(int position, 
 View convertView, ViewGroup parent) { 
 TextView text; 
 
 if (convertView == null) { 
 text = (TextView)mInflater.inflate 
 (android.R.layout.simple_list_item_1, 
 parent, false); 
 } else { 
 text = (TextView)convertView; 
 } 
 
 if (!mBusy) { 
 text.setText(mStrings[position]); 
 // Null tag means the view has the c  
 //orrect data  
 text.setTag(null); 
 } else { 
 text.setText("Loading…"); 
 // Non-null tag means the view still  
 //needs to load it's data  
 text.setTag(this); 
 } 
 
 return text; 

public View getView(int position,
 View convertView, ViewGroup parent) {
 TextView text;

 if (convertView == null) {
 text = (TextView)mInflater.inflate
 (android.R.layout.simple_list_item_1,
 parent, false);
 } else {
 text = (TextView)convertView;
 }

 if (!mBusy) {
 text.setText(mStrings[position]);
 // Null tag means the view has the c
 //orrect data
 text.setTag(null);
 } else {
 text.setText("Loading…");
 // Non-null tag means the view still
 //needs to load it's data
 text.setTag(this);
 }

 return text;
}

可以看到在ListView busy(滾動時) ,將textview 的文字設置成臨時數據(loading …”) ,並把textView 的tag 設為非空, TextView 的Tag 可以使用任何對象,本例用它來做個標記,非空時表示當前TextView使用的是臨時數據。 而的ListView不忙時(停止滾動),將TextView設置成實際需要顯示的文字(或是其它費時的操作),並把它的Tag設為空,表示TextView顯示的是真實數據。

為ListView 添加滾動事件處理

[java] 
getListView().setOnScrollListener(this);} 
… 
 
public void onScrollStateChanged(AbsListView view, 
 int scrollState) { 
 switch (scrollState) { 
 case OnScrollListener.SCROLL_STATE_IDLE: 
 mBusy = false; 
 
 int first = view.getFirstVisiblePosition(); 
 int count = view.getChildCount(); 
 for (int i=0; i<count; i++) { 
 TextView t = (TextView)view.getChildAt(i); 
 if (t.getTag() != null) { 
 t.setText(mStrings[first + i]); 
 t.setTag(null); 
 } 
 } 
 
 mStatus.setText("Idle"); 
 break; 
 case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL: 
 mBusy = true; 
 mStatus.setText("Touch scroll"); 
 break; 
 case OnScrollListener.SCROLL_STATE_FLING: 
 mBusy = true; 
 mStatus.setText("Fling"); 
 break; 
 } 

getListView().setOnScrollListener(this);}

public void onScrollStateChanged(AbsListView view,
 int scrollState) {
 switch (scrollState) {
 case OnScrollListener.SCROLL_STATE_IDLE:
 mBusy = false;

 int first = view.getFirstVisiblePosition();
 int count = view.getChildCount();
 for (int i=0; i<count; i++) {
 TextView t = (TextView)view.getChildAt(i);
 if (t.getTag() != null) {
 t.setText(mStrings[first + i]);
 t.setTag(null);
 }
 }

 mStatus.setText("Idle");
 break;
 case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
 mBusy = true;
 mStatus.setText("Touch scroll");
 break;
 case OnScrollListener.SCROLL_STATE_FLING:
 mBusy = true;
 mStatus.setText("Fling");
 break;
 }
}

在ListView 滾動或是飛速滑動時,將busy設為true, 當滾動停止時SCROLL_STATE_IDLE ,busy為false, 並根據TextView的Tag值判斷是否需要顯示實際的文字串。

本例最下面並使用瞭一個文本框顯示瞭當前ListView的滾動狀態。

 

 

 

 

 

 

 

You May Also Like