今天继续和大家分享涉及到listview的内容。在很多时候,我们会用到 listview和checkbox配合来提供给用户一些选择操作。比如在一个清单页面,我们需要记录用户勾选了哪些条目。这个的实现并不太难,但是有很 多朋友来问我如何实现,他们有遇到各种各样的问题,这里就一并写出来和大家一起分享。
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" android:layout_width= "fill_parent" |
03 | android:layout_height= "fill_parent" |
04 | android:orientation= "horizontal" > |
06 | android:id= "@+id/item_tv" |
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<Integer,boolean>的键值来记录checkbox在对应位置的选中状况,这是本例的实现的基础。
01 | package com.notice.listcheck; |
02 | import java.util.ArrayList; |
03 | import java.util.HashMap; |
04 | import android.content.Context; |
05 | import android.view.LayoutInflater; |
06 | import android.view.View; |
07 | import android.view.ViewGroup; |
08 | import android.widget.BaseAdapter; |
09 | import android.widget.CheckBox; |
10 | import android.widget.TextView; |
11 | public class MyAdapter extends BaseAdapter{ |
13 | private ArrayList<String> list; |
15 | private static HashMap<Integer,Boolean> isSelected; |
17 | private Context context; |
19 | private LayoutInflater inflater = null ; |
21 | public MyAdapter(ArrayList<String> list, Context context) { |
22 | this .context = context; |
24 | inflater = LayoutInflater.from(context); |
25 | isSelected = new HashMap<Integer, Boolean>(); |
30 | private void initDate(){ |
31 | for ( int i= 0 ; i<list.size();i++) { |
32 | getIsSelected().put(i, false ); |
36 | public int getCount() { |
40 | public Object getItem( int position) { |
41 | return list.get(position); |
44 | public long getItemId( int position) { |
48 | public View getView( int position, View convertView, ViewGroup parent) { |
49 | ViewHolder holder = null ; |
50 | if (convertView == null ) { |
52 | holder = new ViewHolder(); |
54 | convertView = inflater.inflate(R.layout.listviewitem, null ); |
55 | holder.tv = (TextView) convertView.findViewById(R.id.item_tv); |
56 | holder.cb = (CheckBox) convertView.findViewById(R.id.item_cb); |
58 | convertView.setTag(holder); |
61 | holder = (ViewHolder) convertView.getTag(); |
64 | holder.tv.setText(list.get(position)); |
66 | holder.cb.setChecked(getIsSelected().get(position)); |
69 | public static HashMap<Integer,Boolean> |
73 | public static void setIsSelected(HashMap<Integer,Boolean> isSelected) { |
74 | MyAdapter.isSelected = isSelected; |
注释已经写的非常详尽了,通过
1 | holder.cb.setChecked(getIsSelected().get(position)); |
这行代码我们实现了设置CheckBox的选中状况。 那么我们只需要在点击事件中,控制isSelected的键值即可控制对应位置checkbox的选中了。 在Activity中我们除了放置一个ListView外,还放置了三个按钮,分别实现全选,取消和反选。 看下Activity类的代码:
001 | package com.notice.listcheck; |
002 | import java.util.ArrayList; |
003 | import android.app.Activity; |
004 | import android.os.Bundle; |
005 | import android.view.View; |
006 | import android.view.View.OnClickListener; |
007 | import android.widget.AdapterView; |
008 | import android.widget.AdapterView.OnItemClickListener; |
009 | import android.widget.Button; |
010 | import android.widget.ListView; |
011 | import android.widget.TextView; |
012 | public class Ex_checkboxActivity extends Activity { |
014 | private MyAdapter mAdapter; |
015 | private ArrayList<String> list; |
016 | private Button bt_selectall; |
017 | private Button bt_cancel; |
018 | private Button bt_deselectall; |
019 | private int checkNum; |
020 | private TextView tv_show; |
021 | /** Called when the activity is first created. */ |
023 | public void onCreate(Bundle savedInstanceState) { |
024 | super .onCreate(savedInstanceState); |
025 | setContentView(R.layout.main); |
027 | lv = (ListView) findViewById(R.id.lv); |
028 | bt_selectall = (Button) findViewById(R.id.bt_selectall); |
029 | bt_cancel = (Button) findViewById(R.id.bt_cancelselectall); |
030 | bt_deselectall = (Button) findViewById(R.id.bt_deselectall); |
031 | tv_show = (TextView) findViewById(R.id.tv); |
032 | list = new ArrayList<String>(); |
036 | mAdapter = new MyAdapter(list, this ); |
038 | lv.setAdapter(mAdapter); |
040 | bt_selectall.setOnClickListener( new OnClickListener() { |
042 | public void onClick(View v) { |
044 | for ( int i = 0 ; i < list.size(); i++) { |
045 | MyAdapter.getIsSelected().put(i, true ); |
048 | checkNum = list.size(); |
054 | bt_cancel.setOnClickListener( new OnClickListener() { |
056 | public void onClick(View v) { |
058 | for ( int i = 0 ; i < list.size(); i++) { |
059 | if (MyAdapter.getIsSelected().get(i)) { |
060 | MyAdapter.getIsSelected().put(i, false ); |
069 | bt_deselectall.setOnClickListener( new OnClickListener() { |
071 | public void onClick(View v) { |
073 | for ( int i = 0 ; i < list.size(); i++) { |
074 | if (MyAdapter.getIsSelected().get(i)) { |
075 | MyAdapter.getIsSelected().put(i, false ); |
078 | MyAdapter.getIsSelected().put(i, true ); |
087 | lv.setOnItemClickListener( new OnItemClickListener() { |
089 | public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, |
092 | ViewHolder holder = (ViewHolder) arg1.getTag(); |
096 | MyAdapter.getIsSelected().put(arg2, holder.cb.isChecked()); |
098 | if (holder.cb.isChecked() == true ) { |
104 | tv_show.setText( "已选中" +checkNum+ "项" ); |
109 | private void initDate() { |
110 | for ( int i = 0 ; i < 15 ; i++) { |
111 | list.add( "data" + " " + i); |
115 | private void dataChanged() { |
117 | mAdapter.notifyDataSetChanged(); |
119 | tv_show.setText( "已选中" + checkNum + "项" ); |
代码中在item的点击事件中,直接调用
先改变CheckBox的状态,然后将值存进map记录下来
1 | MyAdapter.getIsSelected().put(arg2, holder.cb.isChecked()); |
而其他几个Button的点击事件,都是通过遍历list的长度来设置isSelected的值,进而通知listview根据已经变化的 adapter刷新,来实现Checkbox的对应选中状态。因为对listview的处理中我们仍然使用了ViewHolder来优化ListView 的效率(通过findViewById层层查找是比较耗时的
文章转载自:eoeAndroid开发者社区 [http://www.eoeandroid.com]