1. 程式人生 > >本人原創!解決安卓ListView複用問題最簡單的兩種方法。

本人原創!解決安卓ListView複用問題最簡單的兩種方法。

        ListView在安卓很多地方需要用得到,其實listview是基於MVC架構設計的,即資料model,檢視view和控制器controller。安卓已幫我們寫好該框架,我們只需往裡面塞資料就行。對於一些簡單的listview,我們常用arrayadapter來作為介面卡,但這往往不能達到我們想要的結果,為了介面的功能和美觀,我們往往需要自定義介面卡。而介面卡的基類baseadapter安卓已幫我們寫好,我們只需繼承該類,實現裡面的方法即可。

    那麼問題來了,安卓已幫我們設計好的介面卡,有一個特點,就是會複用listview中每一個item所對應的view。這是什麼意思呢?簡單說就是如果你的listview中的item比較多,超出了螢幕,那麼系統就會儲存你當前顯示在螢幕中的listview的item所對應的view物件,當你listview滑動的時候,螢幕外邊滑進來的item所對應的view物件是之前系統所儲存好的物件,這樣的作用是起到一個緩衝的效果,使得資源得到最大化利用,效能得到最大化的優化。
    雖然重用可以使資源最大化利用,但是也帶來了一些問題。因為重用的view的物件是同一個,所以,當開發者在使用view進行操作的時候回發現,其所對應的重用的view也發生了操作響應。舉一個例子,一個listview有四個item,分別是a,b,c,d。其中abc在一個螢幕裡面,d在螢幕下。當你滑到d的時候,d就會使用a所對應的view物件來顯示。那麼當你對a中某一個控制元件進行點選的時候,b中對應的那個控制元件也會發生響應,是不是感覺很蛋疼?這都是因為介面卡中的getView()方法重用資源的原因。我們來看下程式碼:         @Override
public View getView(int position, View convertView, ViewGroup parent) {
         return null;     }   listview每顯示一個item,該方法就會被呼叫一次,第一個引數是listview中的索引,第二個引數顯示在每一個item上面的view物件。      若當前listview剛剛被建立,則convertview就需要我們生成,若listview被滑動到第二第三第四。。屏的時候,系統會將第一屏所儲存好的view傳過來,就是此時的convertView,這就是指listview的重用。      那對於這種情況,筆者想了兩種方法: 第一種:     @Override
public View getView(int position, View convertView, ViewGroup parent) {
              //若listview向下滾動,則在listview生成item的view的時候,將view都儲存進一個集合    
   if(position+1>viewlist.size()){
LayoutInflater inflater=LayoutInflater.from(context);
convertView=inflater.inflate(R.layout.query_listview_item, null);
viewlist.add(convertView);}
                   //若listview往回滾動,則將集合中儲存好的view賦值給convertview。
   else{
   convertView=viewlist.get(position);
   }

                 //下面是一些view的操作,這裡不需要看
TextView cardtextview=(TextView) convertView.findViewById(R.id.cardnumbertextview);
TextView nametextview=(TextView) convertView.findViewById(R.id.nametextview);
cardtextview.setText(list.get(position).cardNumber);
nametextview.setText(list.get(position).name);

return convertView;
}
第二種方法: public class QueryListViewAdapter extends BaseAdapter {
public List<CardsData> list;
public Context context;
public List<View> viewlist=new ArrayList<View>();
public View view;
    @SuppressLint("InflateParams") public QueryListViewAdapter(List<CardsData> list,Context context){
      this.list=list;
      this.context=context;
      viewlist=new ArrayList<View>();
      LayoutInflater inflater=LayoutInflater.from(context);
           //list是存放資料的集合,生成和資料個數一樣的view,即將所用的item所對應的view都生成好。
      for(int x=0;x<list.size();x++){
      view=inflater.inflate(R.layout.query_listview_item, null);
      TextView cardtextview=(TextView) view.findViewById(R.id.cardnumbertextview);
    TextView nametextview=(TextView) view.findViewById(R.id.nametextview);
    cardtextview.setText(list.get(x).cardNumber);
    nametextview.setText(list.get(x).name);
      viewlist.add(view);
      }
    }
      //然後根據索引來給對應的convertView賦值       public View getView(int position, View convertView, ViewGroup parent) {
           convertView=viewlist.get(position);
           return convertView;        } 兩種方法的區別:兩種方法都能避免重用問題,但是第一種方法只適合對單個item進行操作,第二種方法適合對所有item進行操作,比如說你需要點選一個item的控制元件,其他所有item的控制元件也會作出相應,這時需要用第二種方法。 兩種方法都是本人原創,若有不正之處,還望指正,謝謝!!!