android的listview加checkbox实现单保存checkbox的勾选信息

最近做一个项目时想要增加安卓端的一个功能,就是增加一个activity上面有很多checkbox的勾选信息,然后可以给人选择多选框,看起来还算很简单。。但是真正做起来就有很多麻烦了。。

虽然我对安卓有点了解,以前也看过一些代码,但都是看别人的代码,看代码当然简单啦,这下要全部自己写,这下有点棘手了,一开始真是无从下手啊,后来去网上查了一下,觉得有个人的写法不错,就是用listview导入adapter的布局这样子,于是我就照着他的代码的原型开始改了起来。

改了N久,终于改的有点样子了,其中也花了很多精力呢!!所以趁热先记录下来,免得以后忘了,忘了再写的话那可是事倍工半呢!

我新添加的代码有四个文件,分别是Adapter.java,ListViewDemo,java,choice.xml,problem_item.xml这四个文件。

遇到的问题及解决方案:

1.新建的多选框选定以后跳转到别的界面后再次点入这个界面后以前的多选框信息不能保存,这样选择的信息就不能记录下来了。

解决方案:应用preference进行保存,将多选框选择信息写进了preference后下一次再次进入这个界面后就读取初始化信息来进行读取以前的记录信息。从而将多选框的记录勾上。

2.preference只能以键值对来保存,当这个activity有多个其他的信息框调用时,就会产生不能记录所有的多选框选择信息,举个例子,就好像有100个学生,你要为每个学生的类别进行多选框操作,比如说选择上课科目之类的,科目的哪个activity是一样的,但是数据不一样,这样你就需要保存多选框数据了,保存一个还好,但要保存每一个人的信息的话就需要动一番脑筋了。

解决方案:将每一个学生的ID发送到选择框activity,每次打开时读取对应学生ID对于的键值,因为多选框,所以有多个值,为了方便我就将全部的多选框转换为01字符串,0代表没有选中,1代表选中。然后再解析出是否被选中就可以了。

下面是相应功能代码,只供借鉴,不足望指出:

Adapter.java

public class Adapter extends BaseAdapter{

	private ArrayList<String> list;//填充数据的list
	private static HashMap<Integer,Boolean> isSelected;//用来控制checkBox的选中情况
	private Context context;//上下文
	private LayoutInflater inflater=null;//用来导入布局

	public Adapter(ArrayList<String> list,Context context)//构造器
	{
		this.context = context;
		this.list = list;
		inflater = LayoutInflater.from(context);
		isSelected = new HashMap<Integer, Boolean>();
		initDate();//初始化数据
	}

	//初始化选择判断为false
	private void initDate()
	{
		for(int i=0;i<list.size();i++)
		{
			isSelected.put(i, false);
		}
	}

	@Override
	public int getCount() {
		// TODO Auto-generated method stub
		return list.size();
	}

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

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

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		// TODO Auto-generated method stub
		ViewHolder holder = null;
		if(convertView==null)
		{
			holder = new ViewHolder();
			convertView=inflater.inflate(R.layout.problem_item,null);//导入布局并且赋给convertview
			holder.tv =(TextView)convertView.findViewById(R.id.item_tv);//故障信息
			holder.cb =(CheckBox)convertView.findViewById(R.id.item_cb);//勾选框
			convertView.setTag(holder);
		}
		else
		{
			holder = (ViewHolder) convertView.getTag();
		}
		// 设置list中TextView的显示
        holder.tv.setText(list.get(position));
        // 根据isSelected来设置checkbox的选中状况
        holder.cb.setChecked(getIsSelected().get(position));
        return convertView;
	}

	public static HashMap<Integer,Boolean> getIsSelected() {
        return isSelected;
    }  

	public static void setIsSelected(HashMap<Integer,Boolean> isSelected) {
        Adapter.isSelected = isSelected;
    }

ListViewDemo.java

public class ListViewDemo extends Activity {
	private ListView lv;
    private Adapter mAdapter;
    private ArrayList<String> list;
    private Button bt_selectall;
    private Button bt_cancel;
    private Button bt_deselectall;
    private Button bt_yes;
    private int checkNum; // 记录选中的条目数量
    private TextView tv_show;// 用于显示选中的条目数量
    private int id;//消息编号,用来存储故障标号,从上一个界面传来
    private String defaul="";//默认的全部不勾选
    private String selectall="";//全部勾选

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.choice);  

        Intent i=getIntent();
		Bundle b=i.getBundleExtra("ID");
		id=b.getInt("id");

        /* 实例化各个控件 */
        lv = (ListView)findViewById(R.id.list);
        bt_selectall = (Button) findViewById(R.id.bt_selectall);
        bt_cancel = (Button) findViewById(R.id.bt_cancelselectall);
        bt_deselectall = (Button) findViewById(R.id.bt_deselectall);
        bt_yes=(Button) findViewById(R.id.ok);
        tv_show = (TextView) findViewById(R.id.tv);
        list = new ArrayList<String>();  

        initDate();  

        //初始化勾选框信息,默认都是以未勾选为单位
    	for(int n=0;n<list.size();n++)
    	{
    		defaul =defaul +"0";
    		selectall= selectall +"1";
    	}
        // 为Adapter准备数据  

        // 实例化自定义的MyAdapter
        mAdapter = new Adapter(list, this);
        // 绑定Adapter
        lv.setAdapter(mAdapter);
        getCheck();//获取信息,也可说是初始化信息

//        // 全选按钮的回调接口
        bt_selectall.setOnClickListener(new OnClickListener() {  

            @Override
            public void onClick(View v) {
                // 遍历list的长度,将MyAdapter中的map值全部设为true
                for (int i = 0; i < list.size(); i++) {  

                    Adapter.getIsSelected().put(i, true);
                }
                // 数量设为list的长度
                checkNum = list.size();
                // 刷新listview和TextView的显示
                dataChanged();  

            }
        });
        // 取消按钮的回调接口
        bt_cancel.setOnClickListener(new OnClickListener() {  

            @Override
            public void onClick(View v) {
                // 遍历list的长度,将已选的按钮设为未选
                for (int i = 0; i < list.size(); i++) {  

                    if (Adapter.getIsSelected().get(i)) {
                        Adapter.getIsSelected().put(i, false);
                        checkNum--;// 数量减1
                    }
                }
                // 刷新listview和TextView的显示
                //dataChanged();  

            }
        });  

        // 反选按钮的回调接口
        bt_deselectall.setOnClickListener(new OnClickListener() {  

            @Override
            public void onClick(View v) {
                // 遍历list的长度,将已选的设为未选,未选的设为已选
                for (int i = 0; i < list.size(); i++) {
                    if (Adapter.getIsSelected().get(i)) {
                        Adapter.getIsSelected().put(i, false); 

                        checkNum--;
                    } else {
                        Adapter.getIsSelected().put(i, true); 

                        checkNum++;
                    }  

                }
                // 刷新listview和TextView的显示
                //dataChanged();
            }
        });  

        //确定返回的按钮
        bt_yes.setOnClickListener(new OnClickListener() {  

            @Override
            public void onClick(View v) {  

            	String str="";//确定后直接将信息写入preference保存以备下一次读取使用

            	for(int i=0;i<list.size();i++)
            	{
            		if(Adapter.getIsSelected().get(i))
            		{
            			str= str+'1';
            		}
            		else
            		{
            			str = str+'0';
            		}
            	}

               saveCheck(String.valueOf(id),str);//将数据已字符串形式保存起来,下次读取再用
               finish();

            }
        });  

        //绑定listView的监听器
        lv.setOnItemClickListener(new OnItemClickListener() {  

            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                    long arg3) {
                // 取得ViewHolder对象,这样就省去了通过层层的findViewById去实例化我们需要的cb实例的步骤
            	ViewHolder holder = (ViewHolder) arg1.getTag();
                // 改变CheckBox的状态
                holder.cb.toggle();
                // 将CheckBox的选中状况记录下来
                Adapter.getIsSelected().put(arg2, holder.cb.isChecked());   

            	//

                // 调整选定条目
                if (holder.cb.isChecked() == true) {
                    checkNum++;

                } else {
                    checkNum--;  

                }
                // 用TextView显示
                //tv_show.setText("已选中"+checkNum+"项");  

            }
        });
    }  

    //得到保存在这个activity中的数据
    public void getCheck()
    {

    	SharedPreferences mPerferences=PreferenceManager.getDefaultSharedPreferences(this);//获取默认的preference

    	//获取activity私有的preference
    	SharedPreferences m_private=this.getPreferences(MODE_PRIVATE);
    	String counter=mPerferences.getString(String.valueOf(id), defaul);//如果没有获取到的话默认是0

    	for(int i=0;i<list.size();i++)
    	{
    		if(counter.charAt(i)=='1')
    		{
    			Adapter.getIsSelected().put(i, true);
    		}
    	}

    }

    //保存需要保存的数据
    public void saveCheck(String ID,String data)
    {
    	   //保存shuju
        SharedPreferences mPerferences=PreferenceManager.getDefaultSharedPreferences(this);
        SharedPreferences m_private=this.getPreferences(MODE_PRIVATE);
    	SharedPreferences.Editor mEditor=mPerferences.edit();

    	mEditor.putString(ID, data);
    	mEditor.commit();
    }

    // 初始化数据
    private void initDate() {
        for (int i = 0; i < 15; i++) {
            list.add("data" + "   " + i);
        }
    }  

    // 刷新listview和TextView的显示
    private void dataChanged() {
        // 通知listView刷新
        mAdapter.notifyDataSetChanged();
        // TextView显示最新的选中数目
        //tv_show.setText("已选中" + checkNum + "项");  //这个功能还不完善,保存后再打开没把这个保存进去,会算错。
    }  

choic.xml

<RelativeLayout 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/list"
 	     android:layout_width="fill_parent"
 	     android:layout_height="400dp" />

    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/bt_selectall"
        android:gravity="center" />

     <Button
         android:id="@+id/bt_selectall"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_below="@+id/list"
         android:layout_gravity="bottom"
         android:text="全选" />

      <Button
        android:id="@+id/bt_cancelselectall"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
         android:layout_toRightOf="@+id/bt_selectall"
         android:layout_below="@+id/list"
        android:text="取消选择" />
      <Button
        android:id="@+id/bt_deselectall"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/list"
        android:layout_toRightOf="@+id/bt_cancelselectall"
        android:text="反选" />

       <Button
        android:id="@+id/ok"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/list"
        android:layout_toRightOf="@+id/bt_deselectall"
        android:text="确定" />

</RelativeLayout>

problem_item.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="horizontal" >

    <TextView
        android:id="@+id/item_tv"
        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:clickable="false"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:gravity="center_vertical"
        />

</LinearLayout>

ViewHolder.java

public class ViewHolder {
    public TextView tv = null;
    public CheckBox cb = null;
}

下面是选项的效果图

android的listview加checkbox实现单保存checkbox的勾选信息,布布扣,bubuko.com

时间: 2024-07-30 20:02:06

android的listview加checkbox实现单保存checkbox的勾选信息的相关文章

jquery,checkbox无法用attr()二次勾选

今晨,漂亮的测试妹妹提了个奇怪的bug,说我一功能checkbox时隐时现,比如第一次打开有勾选,第n次打开可能就不选了. 想到与美女有亲密接触机会,马上鸡动起来. 经过偶层层抽次剥茧(da da jiang you),终于知道了原因:attr()在二次选中勾选框时,失效. 比如,如下HTML页面,一点[选中].二点[取消选中].三点[选中],瞧,不行了呗. <!doctype html> <html lang="en"> <head> <me

jquery操作checkbox火狐下第二次无法勾选问题

原来的代码: $('#checkAll').click(function(){ var current = $(this) $('.checkbox').each(function(){ debugger; if(current.is(':checked')) { $(this).attr('checked', true); } else { $(this).attr('checked', false); } }); }) 这样在firefox和chrome浏览器下第二次勾选时,属性改变了,页面

Android之ListView——ArrayAdapter的学习与总结

问题:当ListView选定的ListItem视图中存在一些UI组件,如CheckBox,出于对状态保存的期望,发现当勾选后将列表往下滑再滑回去时,意外地发现状态没有保存 解决过程: 1)思考后想到这个原因是因为重用了convertView,当重用converView时,原先勾选的状态没有保存,又被新的数据源覆盖,重点代码为: if (convertView == null) { convertView = getLayoutInflater().inflate( R.layout.city_l

获取每个勾选的checkbox中的value值

<!--获取每个勾选的checkbox中的value值-->  $.each($('input:checkbox:checked'),function(){                window.alert("你勾选了:"+ $('input[type=checkbox]:checked').length+"个checkbox,其中每个的value值是:"+$(this).val());            }); 原文地址:https://ww

Android 下分批加载数据以及listView使用过程中的优化

需求:在开发过程中,listview加载的数据如果比较大,这时为了提高用户体验感,我们应该事先分批加载以及下拉刷新功能 1.首先,数据访问层需要提供分批加载功能的接口, 代码如下: package com.zaizai.safty.db.dao; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.

Android上拉加载更多ListView——PulmListView

思路 今天带大家实现一个上拉加载更多的ListView.GitHub传送门:PulmListView, 欢迎大家fork&&star. 先带大家理一下思路, 如果我们要实现一个上拉加载更多的ListView, 我们需要实现的功能包括: 一个自定义的ListView, 并且该ListView能够判断当前是否已经处于最底部. 一个自定义的FooterView, 用于在ListView加载更多的过程中进行UI展示. 关联FooterView和ListView, 包括加载时机判断.FooterVi

【转】Android ListView加载不同的item布局

原创教程,转载请保留出处:http://www.eoeandroid.com/thread-72369-1-1.html 最近有需求需要在listView中载入不同的listItem布局,开始没有使用convertView,加载了多个item后导致了内存泄露,所以回来研究convertView在多个listItem布局时的缓存及应用,并且和大家分享 构造Adapter时,没有使用缓存的 convertView,导致内存泄露 示例代码:public View getView(int positio

【Android笔记】listview加载性能优化及有多种listitem布局处理方式

在android开发中Listview是一个很重要的组件,它以列表的形式根据数据的长自适应展示具体内容. 用户可以自由的定义listview每一列的布局,但当listview有大量的数据需要加载的时候,会占据大量内存,影响性能,这时候就需要按需填充并重新使用view来减少对象的创建. ListView加载数据都是在 1 public View getView(int position, View convertView, ViewGroup parent) { 2 3 ...... 4 5 }

Android之ListView异步加载图片且仅显示可见子项中的图片

折腾了好多天,遇到 N 多让人崩溃无语的问题,不过今天终于有些收获了,这是实验的第一版,有些混乱,下一步进行改造细分,先把代码记录在这儿吧. 网上查了很多资料,发现都千篇一律,抄来抄去,很多细节和完整实例都没看到,只有自己一点点研究了,总体感觉 android 下面要显示个图片真不容易啊. 项目主要实现的功能: 异步加载图片图片内存缓存.异步磁盘文件缓存解决使用 viewHolder 后出现的图片错位问题优化列表滚动性能,仅显示可见子项中的图片无需固定图片显示高度,对高度进行缓存使列表滚动时不会