轉自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 }