`

android自定义带多选框的listview并避免出现自动选中另外选项

 
阅读更多
android自定义带多选框的listview


先展示下效果图。


main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </ListView>

</LinearLayout>


自定义列表显示样式  list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"
        android:src="@drawable/ic_launcher" />

   	<LinearLayout 
   	    android:id="@+id/linearlayout1"
   	    android:layout_width="wrap_content"
   	    android:layout_height="wrap_content"
   	    android:layout_toRightOf="@id/image"
   	    android:orientation="vertical"
   	    >
	    <TextView
	        android:id="@+id/name"
	        android:layout_width="wrap_content"
	        android:layout_height="wrap_content"
	        android:textSize="23sp"
	        android:text="TextView" />
	
	    <TextView
	        android:id="@+id/info"
	        android:layout_width="wrap_content"
	        android:layout_height="wrap_content"
	        android:text="TextView" />
	</LinearLayout>
    <CheckBox
        android:id="@+id/box"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
		android:layout_centerVertical="true"
        />
	
</RelativeLayout>


具体代码如下:
package org.hwq.list11;

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

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.Toast;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

public class Main extends Activity {
	List<Map<String,String>> data;
	ListView lv;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        lv = (ListView) findViewById(R.id.listView1);
        data = getData();
//        SimpleAdapter a = new SimpleAdapter(this,data, R.layout.list_item,from,to);
//        lv.setAdapter(a);
        MyAdapter adapter = new MyAdapter(this);
        lv.setAdapter(adapter);
    }
    String[] from = new String[]{
    		"image","name","info"
    };
    int[] to = new int[]{
    		R.id.image,R.id.name,R.id.info
    };
    int[] img = new int[]{
    		R.drawable.a,R.drawable.b,R.drawable.c
    };
    String[] name = new String[]{"诸葛","张飞","关羽","刘备","曹操","曹培","曹仁","董卓","吕布","貂蝉","吕蒙","郭嘉","周瑜"};
    public List<Map<String,String>> getData(){
    	List<Map<String,String>> list = new ArrayList<Map<String,String>>();
    	for(int i=0;i<13;i++){
    		Map<String,String> map = new HashMap<String, String>();
    		map.put("image", ""+img[i%3]);
    		map.put("name", name[i]);
    		map.put("info", "信息技术");
    		list.add(map);
    	}
    	return list;
    }
    public class Holder{
    	public ImageView image;
    	public TextView name;
    	public TextView info;
    	public CheckBox box;
    }
    public class MyAdapter extends BaseAdapter{
    	private LayoutInflater inflater;
    	public MyAdapter(Context context){
    		inflater = LayoutInflater.from(context);
    	}
		@Override
		public int getCount() {
			// TODO Auto-generated method stub
			return data.size();
		}

		@Override
		public Object getItem(int position) {
			// TODO Auto-generated method stub
			return null;
		}

		@Override
		public long getItemId(int position) {
			// TODO Auto-generated method stub
			return 0;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			
			Holder holder = null;
			if(convertView == null){
				holder = new Holder();
				convertView = inflater.inflate(R.layout.list_item, null);
				
				holder.image = (ImageView) convertView.findViewById(R.id.image);
				holder.name = (TextView) convertView.findViewById(R.id.name);
				holder.info = (TextView) convertView.findViewById(R.id.info);
				holder.box = (CheckBox) convertView.findViewById(R.id.box);
				convertView.setTag(holder);
			}else{
				holder = (Holder) convertView.getTag();
			}
			
			holder.image.setImageResource(Integer.parseInt(data.get(position).get("image")));
			holder.name.setText(data.get(position).get("name"));
			holder.info.setText(data.get(position).get("info"));
			holder.box.setId(position);
			holder.box.setOnCheckedChangeListener(new CheckBox.OnCheckedChangeListener() {
				public void onCheckedChanged(CompoundButton buttonView,
						boolean isChecked) {
					CheckBox box  = (CheckBox)buttonView;
					Toast.makeText(Main.this, "box 位置"+box.getId()+data.get(box.getId()).get("name"), 0).show();
				}
			});
			return convertView;
		}
    	
    }
}


      下面将对上述代码,做详细的解释,listView在开始绘制的时候,系统首先调用getCount()函数,根据他的返回值得到listView的长度(这也是为什么在开始的第一张图特别的标出列表长度),然后根据这个长度,调用getView()逐一绘制每一行。如果你的getCount()返回值是0的话,列表将不显示同样return 1,就只显示一行。

  系统显示列表时,首先实例化一个适配器(这里将实例化自定义的适配器)。当手动完成适配时,必须手动映射数据,这需要重写getView()方法。系统在绘制列表的每一行的时候将调用此方法。getView()有三个参数,position表示将显示的是第几行,covertView是从布局文件中inflate来的布局。我们用LayoutInflater的方法将定义好的list_item.xml文件提取成View实例用来显示。然后将xml文件中的各个组件实例化(简单的findViewById()方法)。这样便可以将数据对应到各个组件上了。但是按钮为了响应点击事件,需要为它添加点击监听器,这样就能捕获点击事件。至此一个自定义的listView就完成了,现在让我们回过头从新审视这个过程。系统要绘制ListView了,他首先获得要绘制的这个列表的长度,然后开始绘制第一行,怎么绘制呢?调用getView()函数。在这个函数里面首先获得一个View(实际上是一个ViewGroup),然后再实例并设置各个组件,显示之。好了,绘制完这一行了。那 再绘制下一行,直到绘完为止。


    上面步骤完成后,你会发现,当你点击一个复选框的时候,竟然能看到,有的复选框莫名也自动给点上了。这个很让人郁闷。这其中的问题,本人也搞不明白,希望高手能解答。下面给出解决方案:

   代码:
package org.hwq.listview3;

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

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;


public class Main extends Activity{
	//显示数据
	private List<Map<String,String>> data =new ArrayList<Map<String,String>>();
	private ListView lv;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		init();
		lv = (ListView) findViewById(R.id.listview1);
		//自定义适配器继承BaseAdapter
		MyAdapter adapter = new MyAdapter(this);
		lv.setAdapter(adapter);
	}
	//初始显示数据
	private void init() {
		for(int i=0;i<20;i++){
			Map<String,String> map = new HashMap<String, String>();
			map.put("text", "第"+i+"个记录");
			data.add(map);
		}
	}
	public class MyAdapter extends BaseAdapter{
		LayoutInflater inflater;
		//定义CheckBox是否选上的链表,这个很关键
		List<Boolean> checked ;
		//将要显示的每行View添加到这个map里
		Map<Integer,View> map = new HashMap<Integer,View>();
		public MyAdapter(Context context) {
			inflater = LayoutInflater.from(context);
			//初始化checked链表,都置为false,都没选上
			checked = new ArrayList<Boolean>();
			for(int i=0;i<data.size();i++){
				checked.add(false);
			}
		}
		public int getCount() {
			//必须返回初始的数据行数,因为ListView要显示多少行,从这里取出
			return data.size();
		}
		public Object getItem(int position) {
			return null;
		}
		public long getItemId(int position) {
			return 0;
		}
		//从写getView方法,这个方法是每次ListView要绘制一行记录的时候调用的方法
		public View getView(int position, View v1, ViewGroup parent) {
			View v;
			Holder holder = null;
			if(map.get(position) == null){
				//如果map中没有这个view记录,依照我们自定义的xml文件生成一个view
				v = inflater.inflate(R.layout.list_item, null);
				holder = new Holder();
				holder.text = (TextView) v.findViewById(R.id.text);
				holder.box = (CheckBox) v.findViewById(R.id.box);
				map.put(position, v);
				final int p = position;
				//给CheckBox添加监听器。
				holder.box.setOnClickListener(new OnClickListener() {
					public void onClick(View v) {
						CheckBox b = (CheckBox) v;
						//将相应位置的CheckBox的值改变
						checked.set(p,b.isChecked());
						MyAdapter.this.showData();
					}
				});
				v.setTag(holder);
			}else{
				v = map.get(position);
				holder = (Holder) v.getTag();
			}
			//说明:CheckBox无法在xml中映射到ListView,所以数据初始化的时候,没有CheckBox
			holder.text.setText(data.get(position).get("text"));
			holder.box.setChecked(checked.get(position));
			return v;
		}
		protected void showData() {
			StringBuffer sb = new StringBuffer();
			sb.append("已经选上的记录有:\n");
			for(int i=0;i<checked.size();i++){
				if(checked.get(i)){
					Map<String,String> recode = data.get(i);
					sb.append("第").append(i).append("条记录:").append(recode.get("text")).append("\n");
				}
			}
			Toast.makeText(Main.this, sb.toString(), 1).show();
		}
	}
	public final class Holder{
		public TextView text;
		public CheckBox box;
	}
}
  

list_item.xml
<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout 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/text"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:textSize="25sp"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"
        />
    <CheckBox
        android:id="@+id/box"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        />

</RelativeLayout>

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <ListView
       android:id="@+id/listview1"
       android:layout_width="fill_parent"
       android:layout_height="fill_parent"/>
</LinearLayout>


  • 大小: 20.9 KB
分享到:
评论
1 楼 Lifehopeness 2012-07-29  
谢谢分享

相关推荐

    Android自定义弹出多选框,可全选

    通过这种方式,我们成功地实现了Android自定义的弹出多选框,并且加入了全选功能。这样的组件可以方便地在多个场景下复用,提高代码的可维护性和用户体验。在实际开发中,还可以根据需要添加更多的功能,如搜索、...

    android自定义多选对话框

    "android自定义多选对话框"是一个常见的需求,特别是在需要用户从多个选项中进行选择时。在这个主题中,我们将深入探讨如何创建这样一个自定义的多选对话框。 首先,Android的`AlertDialog`类是系统提供的标准...

    ListView添加CheckBox复选框

    本篇文章将详细讲解如何在ListView中实现CheckBox复选框的功能。 首先,我们需要创建一个自定义的ListView适配器。适配器是连接数据源和ListView的关键,它负责将数据转化为可显示的视图。创建一个继承自`...

    android 自定义单选、多选对话框及popwindow窗口实例源码.zip

    通过这些基础,你可以根据提供的“自定义单选、多选对话框及popwindow窗口实例源码”进一步学习和实践,加深对Android自定义对话框和PopWindow的理解。在开发过程中,要注意用户体验,合理使用动画和过渡效果,使...

    (Android)五分钟让你轻松学会ListView单选和多选功能

    为了实现选择功能,我们需要在Item视图中添加可选元素,如复选框或单选按钮。 1. 单选功能: - **RadioButton**:在ListView中实现单选,我们可以为每个Item视图添加一个RadioButton。首先,在布局文件中定义Item...

    listview带可全选全不选删除checkbox

    本教程将详细讲解如何在ListView中实现带可全选、全不选以及删除功能的复选框(Checkbox),确保在操作过程中列表项不会错位。 一、ListView的基本使用 1. 创建ListView:首先,在布局文件中添加ListView控件,并...

    多选框checkbox

    android:text="自定义多选框" /&gt; ``` 6. 在列表视图中使用多选框: 当需要在ListView或RecyclerView中使用多选框时,通常会结合Adapter来实现。每个列表项中包含一个CheckBox,并在onCheckedChanged中更新数据...

    android多选框

    在Android开发中,多选框(CheckBox)是用户界面中常用的一种组件,它允许用户对多个选项进行选择或取消选择。在本示例中,我们将探讨如何实现一个基于多选框的省市区选择功能,这通常涉及到自定义对话框(Dialog)...

    支持单选、多选、全选、全不选、自定义模式的listview

    本示例着重介绍如何实现一个功能丰富的ListView,支持单选、多选、全选、全不选以及自定义选择模式。以下是对这些功能的详细解释: 1. **单选模式**:在单选模式下,ListView中的每一项只能有一个被选中。通常情况...

    android复选框的使用

    在Android开发中,复选框(CheckBox)是一种常用的UI组件,它允许用户在多个选项中进行多选。本文将深入探讨Android复选框的使用,包括其属性设置、事件监听以及实际应用中的常见操作。 首先,让我们了解复选框的...

    android 平台软件复选框控件开发包

    在Android平台上,复选框(Checkbox)控件是用户界面(UI)设计中不可或缺的一部分,它允许用户在多个选项中进行多选操作。这个“android 平台软件复选框控件开发包”可能包含了一些示例代码、教程或者自定义实现,...

    自定义的ListView结合RadioButton显示对话框列表数据

    在Android开发中,自定义的ListView结合RadioButton显示对话框列表数据是一种常见的用户界面设计,用于在弹出的对话框中展示一系列可选的列表项。这样的设计能够为用户提供清晰的选择方式,同时保持屏幕的整洁。以下...

    下拉多选框(使用popupwindow实现)

    在Android开发中,下拉多选框是一种常见的用户交互组件,它允许用户在多个选项中进行选择,且这些选项可以通过一个可折叠的弹出窗口显示。在这个案例中,开发者使用了PopupWindow来实现这一功能。PopupWindow是...

    树形多选框

    在这个场景中,"树形多选框"指的是在`ExpandableListView`的每个子项中嵌入多选框,允许用户对多个子项进行选择。这在实现如文件管理器、设置菜单等具有多级选项的应用场景中非常常见。 首先,我们需要理解`...

    ListView 选择模式

    用户通常通过长按来选择项目,或者通过设置复选框进行选择。启用多选模式,使用`listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE)`。在这种模式下,你需要跟踪已选中的项,并在Adapter中更新它们的状态。 3....

    ActionBar实现listview多选操作

    在Android应用开发中,`ActionBar`是位于应用程序顶部的一个组件,它提供了用户与应用交互的重要方式,如显示应用标识、提供导航选项以及显示各种操作。`ActionBar`在Android设计指南中占据重要地位,因为它增强了...

    listview多选与单选模式demo

    5. 提供一个全选/全不选按钮,通过遍历ListView的所有项并调用setItemChecked()方法来实现。 三、实现细节 1. 自定义Adapter:为了灵活地控制ListView中每一项的显示,通常需要创建一个继承自BaseAdapter的自定义...

    完美解决ListView单选和多选的问题

    在某些应用场景中,我们可能需要实现ListView的单选或多选功能,例如在联系人列表中选择多个联系人或者在选项列表中进行单个选项的选择。本文将详细介绍如何在Android中实现ListView的单选和多选。 ### 1. 单选功能...

    自定义RadioButton

    7. **多选框CheckBox与RadioButton的区别**:虽然在名字上相似,但CheckBox支持多选,而RadioButton只支持单选。在设计自定义控件时,需要注意这两者之间的逻辑差异。 8. **自定义属性**:通过定义自定义属性并使用...

    二级Android可展开的列表(带展开动画的expandlistview)

    为了实现这一功能,你需要在适配器中维护选中状态的逻辑,比如通过`CheckedTextView`展示复选框,并在点击事件中更新选中状态。同时,还需要处理全选和反选的功能,这可能涉及到遍历所有子项并统一设置选中状态。 5...

Global site tag (gtag.js) - Google Analytics