android ListView使用

 
項目要用到一個listview,要求是可以顯示圖片,後面還有有複選框。

先新建一個MyAdapter類,繼承自BaseAdapter。在MyAdapter中實現對數據的綁定,我這兒由於是測試的,所以把數據寫死了。
Java代碼 複製代碼 收藏代碼
  1. package com.zwq.umeng;   
  2.   
  3. import java.util.ArrayList;   
  4. import java.util.HashMap;   
  5. import java.util.List;   
  6. import java.util.Map;   
  7.   
  8. import android.content.Context;   
  9. import android.view.LayoutInflater;   
  10. import android.view.View;   
  11. import android.view.ViewGroup;   
  12. import android.widget.BaseAdapter;   
  13. import android.widget.CheckBox;   
  14. import android.widget.ImageView;   
  15. import android.widget.TextView;   
  16.   
  17. public class MyAdapter extends BaseAdapter {   
  18.     private LayoutInflater mInflater;   
  19.     private List<Map<String, Object>> mData;   
  20.     public static Map<Integer, Boolean> isSelected;   
  21.   
  22.     public MyAdapter(Context context) {   
  23.         mInflater = LayoutInflater.from(context);   
  24.         init();   
  25.     }   
  26.   
  27.     //初始化   
  28.     private void init() {   
  29.         mData=new ArrayList<Map<String, Object>>();   
  30.         for (int i = 0; i < 5; i++) {   
  31.             Map<String, Object> map = new HashMap<String, Object>();   
  32.             map.put("img", R.drawable.icon);   
  33.             map.put("title""第" + (i + 1) + "行的標題");   
  34.             mData.add(map);   
  35.         }   
  36.         //這兒定義isSelected這個map是記錄每個listitem的狀態,初始狀態全部爲false。   
  37.         isSelected = new HashMap<Integer, Boolean>();   
  38.         for (int i = 0; i < mData.size(); i++) {   
  39.             isSelected.put(i, false);   
  40.         }   
  41.     }   
  42.   
  43.     @Override  
  44.     public int getCount() {   
  45.         return mData.size();   
  46.     }   
  47.   
  48.     @Override  
  49.     public Object getItem(int position) {   
  50.         return null;   
  51.     }   
  52.   
  53.     @Override  
  54.     public long getItemId(int position) {   
  55.         return 0;   
  56.     }   
  57.   
  58.     @Override  
  59.     public View getView(int position, View convertView, ViewGroup parent) {   
  60.         ViewHolder holder = null;   
  61.         //convertView爲null的時候初始化convertView。   
  62.         if (convertView == null) {   
  63.             holder = new ViewHolder();   
  64.             convertView = mInflater.inflate(R.layout.vlist, null);   
  65.             holder.img = (ImageView) convertView.findViewById(R.id.img);   
  66.             holder.title = (TextView) convertView.findViewById(R.id.title);   
  67.             holder.cBox = (CheckBox) convertView.findViewById(R.id.cb);   
  68.             convertView.setTag(holder);   
  69.         } else {   
  70.             holder = (ViewHolder) convertView.getTag();   
  71.         }   
  72.         holder.img.setBackgroundResource((Integer) mData.get(position).get(   
  73.                 "img"));   
  74.         holder.title.setText(mData.get(position).get("title").toString());   
  75.         holder.cBox.setChecked(isSelected.get(position));   
  76.         return convertView;   
  77.     }   
  78.   
  79.     public final class ViewHolder {   
  80.         public ImageView img;   
  81.         public TextView title;   
  82.         public CheckBox cBox;   
  83.     }   
  84. }  
package com.zwq.umeng;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;

public class MyAdapter extends BaseAdapter {
	private LayoutInflater mInflater;
	private List<Map<String, Object>> mData;
	public static Map<Integer, Boolean> isSelected;

	public MyAdapter(Context context) {
		mInflater = LayoutInflater.from(context);
		init();
	}

	//初始化
	private void init() {
		mData=new ArrayList<Map<String, Object>>();
		for (int i = 0; i < 5; i++) {
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("img", R.drawable.icon);
			map.put("title", "第" + (i + 1) + "行的標題");
			mData.add(map);
		}
		//這兒定義isSelected這個map是記錄每個listitem的狀態,初始狀態全部爲false。
		isSelected = new HashMap<Integer, Boolean>();
		for (int i = 0; i < mData.size(); i++) {
			isSelected.put(i, false);
		}
	}

	@Override
	public int getCount() {
		return mData.size();
	}

	@Override
	public Object getItem(int position) {
		return null;
	}

	@Override
	public long getItemId(int position) {
		return 0;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		ViewHolder holder = null;
		//convertView爲null的時候初始化convertView。
		if (convertView == null) {
			holder = new ViewHolder();
			convertView = mInflater.inflate(R.layout.vlist, null);
			holder.img = (ImageView) convertView.findViewById(R.id.img);
			holder.title = (TextView) convertView.findViewById(R.id.title);
			holder.cBox = (CheckBox) convertView.findViewById(R.id.cb);
			convertView.setTag(holder);
		} else {
			holder = (ViewHolder) convertView.getTag();
		}
		holder.img.setBackgroundResource((Integer) mData.get(position).get(
				"img"));
		holder.title.setText(mData.get(position).get("title").toString());
		holder.cBox.setChecked(isSelected.get(position));
		return convertView;
	}

	public final class ViewHolder {
		public ImageView img;
		public TextView title;
		public CheckBox cBox;
	}
}

上面類中要注意getView()方法中對數據的處理。
convertView可以認爲是元素的緩存,因爲元素本身沒有變化,因此可以判斷如果非空,就可以複用。減少重複new新對象,系統不斷回收所帶來的內存消耗!
具體可以參考這兒的文章:http://marshal.easymorse.com/archives/3944

接下要新建一個list.xml文件,這個就是佈局image、textview、checkbox。
Java代碼 複製代碼 收藏代碼
  1. <?xml version="1.0" encoding="utf-8"?>   
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="horizontal"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent"  
  6.     >   
  7.     <ImageView   
  8.         android:id="@+id/img"  
  9.         android:layout_width="wrap_content"  
  10.         android:layout_height="wrap_content"  
  11.         android:layout_gravity="center_vertical"/>   
  12.     <TextView    
  13.         android:id="@+id/title"  
  14.         android:textSize="18dip"  
  15.         android:layout_weight="1"  
  16.         android:layout_width="wrap_content"  
  17.         android:layout_height="wrap_content"/>   
  18.     <CheckBox   
  19.         android:id="@+id/cb"  
  20.         android:layout_width="wrap_content"  
  21.         android:layout_height="wrap_content"  
  22.         android:focusable="false"  
  23.         android:focusableInTouchMode="false"  
  24.         android:clickable="false"          
  25.         android:checkMark="?android:attr/listChoiceIndicatorMultiple"/>   
  26. </LinearLayout>  
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <ImageView
    	android:id="@+id/img"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:layout_gravity="center_vertical"/>
    <TextView 
    	android:id="@+id/title"
		android:textSize="18dip"
		android:layout_weight="1"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"/>
	<CheckBox
		android:id="@+id/cb"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:focusable="false"
        android:focusableInTouchMode="false"
        android:clickable="false"		
		android:checkMark="?android:attr/listChoiceIndicatorMultiple"/>
</LinearLayout>

android:layout_weight="1"這一句可以使中間的textview權重增大,從而後面的checkbok可以居右顯示。
android:focusable="false"
        android:focusableInTouchMode="false"
        android:clickable="false"
這三句很重要,如果不加就會出現錯誤。
由於checkbox的點擊事件優先級比listview的高,所以要在checkbox中添加android:focusable="false",使得checkbox初始的時候沒有獲取焦點。
接下來在main.xml中添加Listview組件
Java代碼 複製代碼 收藏代碼
  1. <ListView   
  2.         android:id="@+id/lv"  
  3.         android:layout_width="fill_parent"    
  4.         android:layout_height="wrap_content"/>  
<ListView
		android:id="@+id/lv"
    	android:layout_width="fill_parent" 
    	android:layout_height="wrap_content"/>

接下來就是在activity中調用:
Java代碼 複製代碼 收藏代碼
  1. list=(ListView)findViewById(R.id.lv);   
  2.         MyAdapter adapter=new MyAdapter(this);   
  3.         list.setAdapter(adapter);   
  4.         list.setItemsCanFocus(false);   
  5.         list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);   
  6.   
  7.         list.setOnItemClickListener(new OnItemClickListener(){   
  8.             @Override  
  9.             public void onItemClick(AdapterView<?> parent, View view,   
  10.                     int position, long id) {   
  11.                 ViewHolder vHollder = (ViewHolder) view.getTag();   
  12. //在每次獲取點擊的item時將對於的checkbox狀態改變,同時修改map的值。   
  13.                 vHollder.cBox.toggle();   
  14.                 MyAdapter.isSelected.put(position, vHollder.cBox.isChecked());   
  15.             }   
  16.         });  
list=(ListView)findViewById(R.id.lv);
		MyAdapter adapter=new MyAdapter(this);
		list.setAdapter(adapter);
		list.setItemsCanFocus(false);
		list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);

		list.setOnItemClickListener(new OnItemClickListener(){
			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				ViewHolder vHollder = (ViewHolder) view.getTag();
//在每次獲取點擊的item時將對於的checkbox狀態改變,同時修改map的值。
				vHollder.cBox.toggle();
				MyAdapter.isSelected.put(position, vHollder.cBox.isChecked());
			}
		});

最新看一下效果圖:



要獲取哪些項目被選擇了,可以這樣測試:
Java代碼 複製代碼 收藏代碼
  1. OnClickListener bPop = new OnClickListener() {   
  2.         @Override  
  3.         public void onClick(View v) {   
  4.             for(int i=0;i<list.getCount();i++){   
  5.                 if(MyAdapter.isSelected.get(i)){   
  6.                     ViewHolder vHollder = (ViewHolder) list.getChildAt(i).getTag();   
  7. Log.i(TAG, "--onClick --"+vHollder.title.getText());   
  8.                 }   
  9.             }   
  10.         }   
  11.     };  
OnClickListener bPop = new OnClickListener() {
		@Override
		public void onClick(View v) {
			for(int i=0;i<list.getCount();i++){
				if(MyAdapter.isSelected.get(i)){
					ViewHolder vHollder = (ViewHolder) list.getChildAt(i).getTag();
Log.i(TAG, "--onClick --"+vHollder.title.getText());
				}
			}
		}
	};


總結:
1、ListView的android:cacheColorHint="#00000000"會消除listview拖動時的全選效果。
2、ListView的getView()方法只獲取當前屏幕可以顯示出的view,對隱藏的,就是拖動可以看見的不會繪製,只有需要顯示的時候才繪製。
3、數據可以在activity中獲取,在初始化adapter的時候當做參數傳遞過去,這樣就可以是list變成動態的。
4、給checkbox添加OnClickListener纔會優先響應list item裏面的checkbox。checkbox的OnClickListener監聽實現方法要寫在getview方法裏面,否則獲取不到position。如果不需要對checkbox做優先響應,不需要給checkbox添加OnClickListener。
5、如果要多選或全選需要新建一個list:
Java代碼 複製代碼 收藏代碼
  1. public static Map<Integer, Boolean> isSelected;  
public static Map<Integer, Boolean> isSelected;

在點擊listview 的item或者checkbox時將isSelected的值做相應改變。
6、如果不指定listview的分割線則會有些粗有些細,我指定了之後可以均勻顯示。給listview添加下面屬性:
Java代碼 複製代碼 收藏代碼
  1. android:divider="#8B8B00"  
  2. android:dividerHeight="1px"  
        android:divider="#8B8B00"
        android:dividerHeight="1px"
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章