[轉]ListView由複雜到簡單

轉自http://www.cnblogs.com/carmanloneliness/archive/2012/02/27/2370597.html

ListView由複雜到簡單

  項目做完了,其中用到的ListView控件很大,有自由的時間就總結一下ListView的各個知識點。談到ListView總是離不開adapter的使用,在這片文章中也總結下adapter的使用,主要講述兩個adapter吧,baseadapter和cursoradapter的使用。這倆是使用頻率最多的adapter。當然還有用系統的adapter,但這個較簡單。到文章最後再舉幾個更復雜的ListView的例子,作爲擴展內容。

  一.在xmlListView應設置爲

  <ListView android:id="@+id/list_goods" 
  android:layout_width="fill_parent" 
  android:layout_height="wrap_content" />。主要就是寬度填滿,高度自適應。

  還有很多很實用的屬性:

  android:cacheColorHint="#00000000"  :ListView上下拖動的時候會出現黑框,如下圖所示。設置左邊的屬性就可完美解決,當然在代碼中也設置該屬性(不推薦).

            

  android:divider="#000000"  該屬性是用來設置ListView 間隔線 的顏色。很實用

  android:dividerHeight="1px" 用來設置  間隔線 的高度,要設置的話一般就是1px,能看出來顏色就OK啦。

  Android中有很多xml屬性可以完美解決的事情,譬如在manifest文件的activity標籤中設置android:theme="@android:style/Theme.NoTitleBar",就可隱藏標題。希望讀者多研究研究這一點,最好不要在Java代碼裏面實現這些功能。

  二:綁定繼承自BaseAdapter的的ListView

  第一次使用自定義adapter理解起來有點複雜,因爲繼承的方法太多,其中最主要的就是getView方法。多聯繫就熟悉啦。自定義adapter的目的無非以下幾點:

  ListView中實現按鈕的監聽:

  要有漂亮圖片的顯示;

  複選框等複雜控件的顯示;

  需求較複雜,系統自帶的adapter滿足不了要求。

  結合最常用的上述幾點要求,弄一個綜合的ListView例子來講述下這些功能的實現。

效果如下圖:

    

  這個例子裏實現了圖片顯示,複選框,按鈕。共用了五個控件,一個ImageView(imageItem),兩個TextView(titleItem,infoItem),一個CheckBox(checkItem),一個Button(detailItem)。在這裏詳細說明下如何定義adapter,Demo的代碼放在附件代碼裏供下載吧。

 

  public ListViewAdapter(Context context, List<Map<String, Object>> listItems) {

    this.listItems = listItems;
    XXXXXXX  
  }

  構造放在的作用是傳入一個listItems,listItems是ListView容器中各個控件顯示的內容,imageItem要顯示的圖片,titleItem和infoItem要顯示的文字以及點擊detailItem彈出對話所顯示的文字,在定義adapter時調用構造方法將設置好的變量傳入adapter當中來,這樣就有內容。接下來就依次介紹下實現BaseAdapter所必須繼承的方法。 

  1.@Override
  public int getCount() {
    // TODO Auto-generated method stub
    return listItems.size();
  }

  這個是ListView中所包含的Item的數量。既然數據都在listItems中,那麼這裏就返回listItems的長度。

  2.@Override

   public Object getItem(int position) {
    // TODO Auto-generated method stub
    return null;
   }

  這裏可以return null.但更專業一點返回listItems.get(position),這樣在getView函數中直接調用getItem(int XX)方法就行了,不用再調用具體的值,更好的提現了封裝性;

  3.@Override

  public long getItemId(int position) {
    // TODO Auto-generated method stub
    return 0;
  }

  和2中同樣的道理,可以return 0,也可以return position.

  4.這個ListView中共有5個控件,控件較多,要定義一個final類型的內部類,來封裝這些控件,如下所示:

    public final class ListItemView{ //自定義控件集合 
      public ImageView image; 
      public TextView title; 
      public TextView info; 
      public CheckBox check; 
      public Button detail; 
    }這樣在getView中賦值的話直接用"變量名.類的變量"就可以了。當然也可以不用聲明內部類,而用變量引用來實現。

  5.最主要的就是接下來的getView方法

getView方法的參數共3個,這三個參數具體含義可查API文檔,講解的比我詳細,返回值就是中間這個變量convertView,getView的方法作用簡單說來就是將第二個參數賦予正確的值並且返回。這其中要注意一點要將convertView綁定4中內部類的一個變量,這才能是convertView設置爲正確的格式。通過setTag的方法來實現該功能。

ListItemView listItemView = null; 
  if (convertView == null) { 
    XXXX
    convertView.setTag(listItemView);  
  }else { 
    listItemView = (ListItemView)convertView.getTag(); 
  }

  若想實現ListView的單雙行不同顏色顯示,或者各行不同顏色顯示,就要在getView方法中實現。舉例,單雙行不同顏色顯示的方法如下:

  if(position % 2 == 0)
    convertView.setBackgroundColor(Color.WHITE);
  else
    convertView.setBackgroundColor(Color.parseColor("#F9F6F1"));

同樣的功能,若是在CursorAdapter中實現,就要在newView方法裏面實現,而不是在bindView裏面實現。

代碼附上!太晚了,就寫到baseAdapter吧,cursoradapter明天寫。想得挺簡單的,一提筆就覺得有很多細節要交代,各位看官將就看吧,若不明,郵件給我[email protected]

                

                                          -Carman

                                          -2010.2.27

 

複製代碼
  1 package a.b;
  2 
  3 import java.util.List;   
  4 import java.util.Map;   
  5 import android.app.AlertDialog;   
  6 import android.content.Context;   
  7 import android.util.Log;   
  8 import android.view.LayoutInflater;   
  9 import android.view.View;   
 10 import android.view.ViewGroup;   
 11 import android.widget.BaseAdapter;   
 12 import android.widget.Button;   
 13 import android.widget.CheckBox;   
 14 import android.widget.CompoundButton;   
 15 import android.widget.ImageView;      
 16 import android.widget.TextView;
 17 
 18 public class ListViewAdapter extends BaseAdapter {
 19     
 20     private Context context;                       
 21     private List<Map<String, Object>> listItems;  
 22     private LayoutInflater listContainer;          
 23     private boolean[] hasChecked;                  
 24     public final class ListItemView{              
 25             public ImageView image;     
 26             public TextView title;     
 27             public TextView info;   
 28             public CheckBox check;   
 29             public Button detail;          
 30      }
 31     public ListViewAdapter(Context context, List<Map<String, Object>> listItems) {   
 32         this.context = context;            
 33         listContainer = LayoutInflater.from(context);   
 34         this.listItems = listItems;   
 35         hasChecked = new boolean[getCount()];   
 36     } 
 37     @Override
 38     public int getCount() {
 40         return listItems.size();
 41     }
 42 
 43     @Override
 44     public Object getItem(int position) {
 45        
 46         return null;
 47     }
 48 
 49     @Override
 50     public long getItemId(int position) {
 51         
 52         return 0;
 53     }
 54     
 55     private void checkedChange(int checkedID) {   
 56         hasChecked[checkedID] = !hasChecked[checkedID];   
 57     }   
 58    
 64     public boolean hasChecked(int checkedID) {   
 65         return hasChecked[checkedID];   
 66     }   
 67    
 72     private void showDetailInfo(int clickID) {   
 73         new AlertDialog.Builder(context)   
 74         .setTitle("物品詳情:" + listItems.get(clickID).get("info"))   
 75         .setMessage(listItems.get(clickID).get("detail").toString())                 
 76         .setPositiveButton("確定", null)   
 77         .show();   
 78     }   
 79     
 80     @Override
 81     public View getView(int position, View convertView, ViewGroup parent) {
 82         
 83         Log.e("method", "getView");   
 84         final int selectID = position;   
 85        
 86         ListItemView  listItemView = null;   
 87         if (convertView == null) {   
 88             listItemView = new ListItemView();    
 89             
 90             convertView = listContainer.inflate(R.layout.list_item, null);   
 91            
 92             listItemView.image = (ImageView)convertView.findViewById(R.id.imageItem);   
 93             listItemView.title = (TextView)convertView.findViewById(R.id.titleItem);   
 94             listItemView.info = (TextView)convertView.findViewById(R.id.infoItem);   
 95             listItemView.detail= (Button)convertView.findViewById(R.id.detailItem);   
 96             listItemView.check = (CheckBox)convertView.findViewById(R.id.checkItem);   
 97            
 98             convertView.setTag(listItemView);   
 99         }else {   
100             listItemView = (ListItemView)convertView.getTag();   
101         }   
102
106         listItemView.image.setBackgroundResource((Integer) listItems.get(   
107                 position).get("image"));   
108         listItemView.title.setText((String) listItems.get(position)   
109                 .get("title"));   
110         listItemView.info.setText((String) listItems.get(position).get("info"));   
111         listItemView.detail.setText("商品詳情");   
112       
113         listItemView.detail.setOnClickListener(new View.OnClickListener() {   
114             @Override  
115             public void onClick(View v) {   
116                
117                 showDetailInfo(selectID);   
118             }   
119         });   
120       
121         listItemView.check   
122                 .setOnCheckedChangeListener(new CheckBox.OnCheckedChangeListener() {   
123                     @Override  
124                     public void onCheckedChanged(CompoundButton buttonView,   
125                             boolean isChecked) {   
126                         
127                         checkedChange(selectID);   
128                     }   
129         });   
130            
131         return convertView;   
132     }
133 }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章