ListView的操作就一定会涉及到item和Adapter,我们还是先来实现这部分内容。 首先,写个item的xml布局,里面放置一个TextView和一个CheckBox。要注意的时候,这里我设置了CheckBox没有焦点,这样的话,无法单独点击checkbox,而是在点击listview的条目后,Checkbox会响应操作。
01 | xml version= "1.0" encoding= "utf-8" ?> |
02 | <LinearLayout xmlns:android= "http://schemas.android.com/apk/res/android" |
03 | android:layout_width= "fill_parent" |
04 | android:layout_height= "fill_parent" |
05 | android:orientation= "horizontal" > |
07 | android:id= "@+id/item_tv" |
08 | android:layout_width= "0dp" |
09 | android:layout_height= "wrap_content" |
10 | android:layout_weight= "1" |
11 | android:gravity= "center_vertical" |
14 | android:id= "@+id/item_cb" |
15 | android:layout_width= "wrap_content" |
16 | android:layout_height= "wrap_content" |
17 | android:clickable= "false" |
18 | android:focusable= "false" |
19 | android:focusableInTouchMode= "false" |
20 | android:gravity= "center_vertical" |
下面就写一个Adapter类,我们依然继承BaseAdapter类。这里我们使用一个HashMap的键值来记录checkbox在对应位置的选中状况,这是本例的实现的基础。
01 | public class MyAdapter extends BaseAdapter{ |
03 | private ArrayList list; |
05 | private static HashMap isSelected; |
07 | private Context context; |
09 | private LayoutInflater inflater = null ; |
11 | public MyAdapter(ArrayList list, Context context) { |
12 | this .context = context; |
14 | inflater = LayoutInflater.from(context); |
15 | isSelected = new HashMap(); |
20 | private void initDate(){ |
21 | for ( int i= 0 ; i getIsSelected().put(i, false ); |
25 | public int getCount() { |
29 | public Object getItem( int position) { |
30 | return list.get(position); |
33 | public long getItemId( int position) { |
37 | public View getView( int position, View convertView, ViewGroup parent) { |
38 | ViewHolder holder = null ; |
39 | if (convertView == null ) { |
41 | holder = new ViewHolder(); |
43 | convertView = inflater.inflate(R.layout.listviewitem, null ); |
44 | holder.tv = (TextView) convertView.findViewById(R.id.item_tv); |
45 | holder.cb = (CheckBox) convertView.findViewById(R.id.item_cb); |
47 | convertView.setTag(holder); |
50 | holder = (ViewHolder) convertView.getTag(); |
53 | holder.tv.setText(list.get(position)); |
55 | holder.cb.setChecked(getIsSelected().get(position)); |
58 | public static HashMap getIsSelected() { |
61 | public static void setIsSelected(HashMap isSelected) { |
62 | MyAdapter.isSelected = isSelected; |
注释已经写的非常详尽了,通过
1 | holder.cb.setChecked(getIsSelected().get(position)); |
这行代码我们实现了设置CheckBox的选中状况。 那么我们只需要在点击事件中,控制isSelected的键值即可控制对应位置checkbox的选中了。 在Activity中我们除了放置一个ListView外,还放置了三个按钮,分别实现全选,取消和反选。 看下Activity类的代码:
001 | public class Ex_checkboxActivity extends Activity { |
004 | private MyAdapter mAdapter; |
005 | private ArrayList list; |
006 | private Button bt_selectall; |
007 | private Button bt_cancel; |
008 | private Button bt_deselectall; |
010 | private TextView tv_show; |
012 | /** Called when the activity is first created. */ |
014 | public void onCreate(Bundle savedInstanceState) { |
015 | super .onCreate(savedInstanceState); |
016 | setContentView(R.layout.main); |
018 | lv = (ListView) findViewById(R.id.lv); |
019 | bt_selectall = (Button) findViewById(R.id.bt_selectall); |
020 | bt_cancel = (Button) findViewById(R.id.bt_cancelselectall); |
021 | bt_deselectall = (Button) findViewById(R.id.bt_deselectall); |
022 | tv_show = (TextView) findViewById(R.id.tv); |
023 | list = new ArrayList(); |
027 | mAdapter = new MyAdapter(list, this ); |
029 | lv.setAdapter(mAdapter); |
031 | bt_selectall.setOnClickListener( new OnClickListener() { |
033 | public void onClick(View v) { |
035 | for ( int i = 0 ; i < list.size(); i++) { |
036 | MyAdapter.getIsSelected().put(i, true ); |
039 | checkNum = list.size(); |
045 | bt_cancel.setOnClickListener( new OnClickListener() { |
047 | public void onClick(View v) { |
049 | for ( int i = 0 ; i < list.size(); i++) { |
050 | if (MyAdapter.getIsSelected().get(i)) { |
051 | MyAdapter.getIsSelected().put(i, false ); |
061 | bt_deselectall.setOnClickListener( new OnClickListener() { |
063 | public void onClick(View v) { |
065 | for ( int i = 0 ; i < list.size(); i++) { |
066 | if (MyAdapter.getIsSelected().get(i)) { |
067 | MyAdapter.getIsSelected().put(i, false ); |
070 | MyAdapter.getIsSelected().put(i, true ); |
080 | lv.setOnItemClickListener( new OnItemClickListener() { |
083 | public void onItemClick(AdapterView arg0, View arg1, int arg2, |
086 | ViewHolder holder = (ViewHolder) arg1.getTag(); |
090 | MyAdapter.getIsSelected().put(arg2, holder.cb.isChecked()); |
092 | if (holder.cb.isChecked() == true ) { |
098 | tv_show.setText( "已选中" +checkNum+ "项" ); |
103 | private void initDate() { |
104 | for ( int i = 0 ; i < 15 ; i++) { |
105 | list.add( "data" + " " + i); |
109 | private void dataChanged() { |
111 | mAdapter.notifyDataSetChanged(); |
113 | tv_show.setText( "已选中" + checkNum + "项" ); |
代码中在item的点击事件中,直接调用 holder.cb.toggle(); 先改变CheckBox的状态,然后将值存进map记录下来 MyAdapter.getIsSelected().put(arg2, holder.cb.isChecked()); 而其他几个Button的点击事件,都是通过遍历list的长度来设置isSelected的值,进而通知listview根据已经变化的adapter刷新,来实现Checkbox的对应选中状态。因为对listview的处理中我们仍然使用了ViewHolder来优化ListView的效率(通过findViewById层层查找是比较耗时的,全面解析listview的),来看下运行效果: |