CheckBox本为复选框,仍然可以当单选框用
自定义ListView item中包含一个textview 和checkbox,checkbox选中级别高于item,故在xml中进行屏蔽
单选方法:(该方法同样适用于radiobutton)
main.xml
- <span style="font-size:14px;"><?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- >
- <ImageView
- android:id="@+id/img"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:src="@drawable/triangle16blue"/>
- <ListView
- android:id="@+id/lvGroup"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:background="@drawable/downbutton_corner"/>
- </LinearLayout></span>
- <span style="font-size:14px;"><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="horizontal" >
- <TextView
- android:id="@+id/item_tv"
- android:textSize="18sp"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:gravity="center_vertical" />
- <CheckBox
- android:id="@+id/item_cb"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:focusable="false"
- android:clickable="false"
- android:focusableInTouchMode="false"
- android:gravity="center_vertical"/>
- </LinearLayout></span>
MainActivity.java
- public class MainActivity extends Activity {
- private static final String TAG = "MainActivity";
- private ListView listView;
- private ArrayList<String> groups;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- listView = (ListView) this.findViewById(R.id.list);
- groups = new ArrayList<String>();
- groups.add("11");
- groups.add("22");
- groups.add("33");
- groups.add("44");
- groups.add("55");
- groups.add("66");
- groups.add("77");
- GroupAdapter adapter = new GroupAdapter(this,groups);
- listView.setAdapter(adapter);
- listView.setOnItemClickListener(listItemClickListener);
- OnItemClickListener listItemClickListener=new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position,
- long id) {
- 取得ViewHolder对象,这样就省去了通过层层的findViewById去实例化我们需要的cb实例的步骤
- ViewHolder viewHolder=(ViewHolder)view.getTag();
- viewHolder.cb.toggle();// 把CheckBox的选中状态改为当前状态的反,gridview确保是单一选中
- }
- };
- }
- }
GroupAdapter.java
- <span style="font-size:14px;">public class GroupAdapter extends BaseAdapter {
- private Activity activity;//上下文
- private ArrayList<String> list;
- private LayoutInflater inflater=null;//导入布局
- private int temp=-1;
- public GroupAdapter(Activity context, ArrayList<String> list) {
- this.activity = context;
- this.list = list;
- inflater=LayoutInflater.from(context);
- }
- @Override
- public int getCount() {
- return list.size();
- }
- @Override
- public Object getItem(int position) {
- return list.get(position);
- }
- @Override
- public long getItemId(int position) {
- // TODO Auto-generated method stub
- return position;
- }
- //listview每显示一行数据,该函数就执行一次
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- ViewHolder holder=null;
- if (convertView==null) {//当第一次加载ListView控件时 convertView为空
- convertView=inflater.inflate(R.layout.group_item_view, null);//所以当ListView控件没有滑动时都会执行这条语句
- holder=new ViewHolder();
- holder.tv=(TextView)convertView.findViewById(R.id.item_tv);
- holder.cb=(CheckBox)convertView.findViewById(R.id.item_cb);
- convertView.setTag(holder);//为view设置标签
- }
- else{//取出holder
- holder=(ViewHolder) convertView.getTag();//the Object stored in this view as a tag
- }
- //设置list的textview显示
- holder.tv.setTextColor(Color.WHITE);
- holder.tv.setText(list.get(position));
- // 根据isSelected来设置checkbox的选中状况
- holder.cb.setId(position);//对checkbox的id进行重新设置为当前的position
- holder.cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
- //把上次被选中的checkbox设为false
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- if(isChecked){//实现checkbox的单选功能,同样适用于radiobutton
- if(temp!=-1){
- //找到上次点击的checkbox,并把它设置为false,对重新选择时可以将以前的关掉
- CheckBox tempCheckBox=(CheckBox)activity.findViewById(temp);
- if(tempCheckBox!=null)
- tempCheckBox.setChecked(false);
- }
- temp=buttonView.getId();//保存当前选中的checkbox的id值
- }
- }
- });
- //System.out.println("temp:"+temp);
- //System.out.println("position:"+position);
- if(position==temp)//比对position和当前的temp是否一致
- holder.cb.setChecked(true);
- else
- holder.cb.setChecked(false);
- return convertView;
- }
- static class ViewHolder {
- TextView tv;
- CheckBox cb;
- }
- }</span>
MainAcitvity.java
- public class MainActivity extends Activity {
- private static final String TAG = "MainActivity";
- private ListView listView;
- private ArrayList<String> groups;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- listView = (ListView) this.findViewById(R.id.list);
- groups = new ArrayList<String>();
- groups.add("11");
- groups.add("22");
- groups.add("33");
- groups.add("44");
- groups.add("55");
- groups.add("66");
- groups.add("77");
- GroupAdapter adapter = new GroupAdapter(this,groups);
- listView.setAdapter(adapter);
- listView.setOnItemClickListener(listItemClickListener);
- OnItemClickListener listItemClickListener=new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position,
- long id) {
- 取得ViewHolder对象,这样就省去了通过层层的findViewById去实例化我们需要的cb实例的步骤
- ViewHolder viewHolder=(ViewHolder)view.getTag();
- viewHolder.cb.toggle();// 把CheckBox的选中状态改为当前状态的反,gridview确保是单一选中
- <span style="color:#ff6666;">GroupAdapter.getIsSelected().put(position, viewHolder.cb.isChecked());//将CheckBox的选中状况记录下来 </span>
- }
- };
- }
- }
GroupAdapter.java
- public class GroupAdapter extends BaseAdapter {
- <span style="color:#ff0000;">private Context context;//上下文</span>
- private ArrayList<String> list;
- //控制CheckBox选中情况
- private static HashMap<Integer,Boolean> isSelected;
- private LayoutInflater inflater=null;//导入布局
- public GroupAdapter(<span style="color:#ff0000;">Context context,</span> ArrayList<String> list) {
- <span style="color:#ff0000;">this.context = context;</span>
- this.list = list;
- inflater=LayoutInflater.from(context);
- isSelected=new HashMap<Integer, Boolean>();
- initData();
- }
- private void initData(){//初始化isSelected的数据
- for(int i=0;i<list.size();i++){
- getIsSelected().put(i,false);
- }
- }
- @Override
- public int getCount() {
- return list.size();
- }
- @Override
- public Object getItem(int position) {
- return list.get(position);
- }
- @Override
- public long getItemId(int position) {
- // TODO Auto-generated method stub
- return position;
- }
- //listview每显示一行数据,该函数就执行一次
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- ViewHolder holder=null;
- if (convertView==null) {//当第一次加载ListView控件时 convertView为空
- convertView=inflater.inflate(R.layout.group_item_view, null);//所以当ListView控件没有滑动时都会执行这条语句
- holder=new ViewHolder();
- holder.tv=(TextView)convertView.findViewById(R.id.item_tv);
- holder.cb=(CheckBox)convertView.findViewById(R.id.item_cb);
- convertView.setTag(holder);//为view设置标签
- }
- else{//取出holder
- holder=(ViewHolder) convertView.getTag();//the Object stored in this view as a tag
- }
- //设置list的textview显示
- holder.tv.setTextColor(Color.WHITE);
- holder.tv.setText(list.get(position));
- // 根据isSelected来设置checkbox的选中状况
- <span style="color:#ff0000;">holder.cb.setChecked(getIsSelected().get(position));</span>
- return convertView;
- }
- static class ViewHolder {
- TextView tv;
- CheckBox cb;
- }
- public static HashMap<Integer, Boolean>getIsSelected(){
- return isSelected;
- }
- public static void setIsSelected(HashMap<Integer, Boolean> isSelected){
- GroupAdapter.isSelected=isSelected;
- }
- }
若要单选,必须保存当前选中的checkbox的position值,与listview 的每一个item的position进行比较,相同时才设置checkbox ischeck=true;
只有checkbox的setOnCheckChangeListener可以做到这点,保存上一次点击的position值,对checkbox的id值重新设置.temp保存该id值.
getview负责显示数据,onitemselectedlistener负责发送消息,提取数据,处理数据
参考:http://blog.csdn.net/notice520/article/details/7266896
http://blog.csdn.net/jdsjlzx/article/details/6969405
http://www.devdiv.com/forum.php?mod=viewthread&tid=85251