今天继续和大家分享涉及到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]