`

Android开发:ListView中Checkbox的处理

阅读更多
  基本功能:读取手机通讯录,形成列表,显示人名、电话,将勾选的信息保存到常用联系人数据库,再次打开时,根据常用联系人数据库中的信息,设置ListView中项目的勾选状态。
  效果如下图所示:




  主要涉及三个文件,详细内容如下:

ListView的子项目,文件名:person_row.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:descendantFocusability="blocksDescendants"
    android:layout_width="match_parent" android:layout_height="match_parent">

    <CheckBox
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:focusable="false"
        android:clickable="false"
        android:id="@+id/contact_checbox" />

    <TextView
        android:layout_width="2dp"
        android:layout_height="wrap_content"
        android:id="@+id/contact_id"
        android:visibility="invisible" />

    <TextView
        android:layout_width="60dp"
        android:layout_height="wrap_content"
        android:text=""
        android:id="@+id/contact_name"
        android:textAlignment="textStart"
        android:background="#ffe222"
        style="@style/style_edit" />

    <TextView
        android:layout_width="90dp"
        android:layout_height="wrap_content"
        android:text=""
        android:id="@+id/contact_mobile"
        android:textAlignment="textStart"
        android:background="#34ff1d"
        style="@style/style_edit" />

    <TextView
        android:layout_width="60dp"
        android:layout_height="wrap_content"
        android:text=""
        android:id="@+id/contact_title"
        android:background="#cafeff" />

    <TextView
        android:layout_width="60dp"
        android:layout_height="wrap_content"
        android:text=""
        android:id="@+id/contact_remark1"
        android:background="#b5aaff"
        style="@style/style_edit" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text=""
        android:id="@+id/contact_remark2" />
</LinearLayout>


布局文件,文件名contact_activity:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context="com.wallimn.iteye.msgutil.ContactActivity">

    <ListView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/contact_list"
        android:layout_alignParentStart="true" />

</RelativeLayout>


JAVA文件,文件名ContactActivity :
package com.wallimn.iteye.msgutil;

import android.app.ProgressDialog;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
import android.provider.ContactsContract;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.CheckedTextView;
import android.widget.CompoundButton;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;

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

public class ContactActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {

    /**
     * 简短的联系人信息类
     */
    public static class ContactDetail{
        public String id;
        public String name;
        public String mobile;
        public String title;
        public String remark1;
        public boolean checked;

        public ContactDetail(String id,String name,String mobile){
            this.id = id;
            this.name = name;
            this.mobile = mobile;
            this.title = "";
            this.remark1="";
        }
        public ContactDetail(String id,String name,String mobile,String title,String remark1){
            this.id = id;
            this.name = name;
            this.mobile = mobile;
            this.title = title;
            this.remark1 = remark1;
        }
    }

    /**
     * 所有联系人列表,读取手机通讯录的结果
     */
    List<ContactDetail> allContacts;

    /**
     * 界面元素
     */
    ListView listView;

    /**
     * 读取联系人的线程
     */
    Thread readContactsThread;
    Handler messageHandler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {

                case UPDATE_LIST:
                    if (proDialog != null) {
                        proDialog.dismiss();
                        proDialog = null;
                    }
                    freshListView();
            }
        }
    };


    private final int UPDATE_LIST=0x3390;
    private ProgressDialog proDialog;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_contact);

        listView = (ListView)this.findViewById(R.id.contact_list);
        listView.setItemsCanFocus(false);
        listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
        listView.setOnItemClickListener(this);

        allContacts = new LinkedList<ContactDetail>();


        readContactsThread=new Thread(new ReadContactsRunnable());
        readContactsThread.start();
        proDialog = ProgressDialog.show(ContactActivity.this, "请稍候","正在读取联系人......", true, true);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_contact, menu);
        return true;
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        //点击菜单上的确定后,将数据保存到本机的数据库中。
        if (id == R.id.menu_ok) {
            Map<String ,String> sels = new HashMap<String ,String>();
            SQLiteDatabase db = DbUtil.getConnection(this);
            Map<String,String> ids = DbUtil.getLocalContactId(db);
            String insertsql = "insert into t_person (name,mobile,contactid) values(?,?,?)";
            String deletesql = "delete from t_person where contactid=?";

            int selCount = 0;
            for(ContactDetail cd:this.allContacts) {
                //如果选中、且本地数据库中没有,插入本地数据库
                if (cd.checked == true) {
                    if (!ids.containsKey(cd.id)) {
                        db.execSQL(insertsql, new String[]{cd.name, cd.mobile, cd.id});
                        Log.i("wallimn", "插入:" + cd.name);
                        selCount++;
                    }
                    sels.put(cd.id, "1");
                }
            }
            Log.i("wallimn", "共计:" + allContacts.size() + ",选中:" + selCount);

            //删除这次未选的。
            for(String key:ids.keySet()){
                if(!sels.containsKey(key)){
                    db.execSQL(deletesql,new Object[]{key});
                }
            }
            db.close();;
            db=null;

            this.finish();
            return true;
        }
        else if(id == R.id.menu_cancel) {
            this.finish();
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    /**
     * 刷新ListView显示
     */
    private void freshListView(){
        Log.i("wallimn","联系人装载完毕,准备生成列表,读取联系人数量:"+allContacts.size());
        if(allContacts!=null){
            ContactAdapter adapter = new ContactAdapter(ContactActivity.this,this.allContacts);

            //读取数据库中保存的常用联系人,如果存在,设置该行为选中状态。
            Map<String,String> ids = DbUtil.getLocalContactId(ContactActivity.this);
            for(ContactDetail cd :allContacts){
                if(ids.containsKey(cd.id))cd.checked=true;
            }
            listView.setAdapter(adapter);
        }
        Log.i("wallimn","列表生成完毕");

    }

    /**
     * 设置了ListView中的checkbox不能获取焦点、不能点击,ListView才会响应这个事件
     * @param parent
     * @param view
     * @param position
     * @param id
     */
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        Log.i("wallimn","ItemClick被点击,position="+position+" , id="+id);
        CheckBox cb = (CheckBox)view.findViewById(R.id.contact_checbox);
        cb.setChecked(!cb.isChecked());
        allContacts.get((int) id).checked = cb.isChecked();
    }

    /**
     * 读取联系人的线程,读取完成后,数据保存到List中,最后发送消息,通知界面更新显示
     */
    class ReadContactsRunnable implements Runnable{
        @Override
        public void run() {
            Uri uri = ContactsContract.Contacts.CONTENT_URI;
            String[] projection = new String[] {
                    ContactsContract.Contacts._ID,
                    ContactsContract.Contacts.DISPLAY_NAME,
                    ContactsContract.Contacts.PHOTO_ID
            };
            String selection = ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '1'";
            String[] selectionArgs = null;
            String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
            ContentResolver contentResolver = ContactActivity.this.getContentResolver();
            Cursor cursor=contentResolver.query(uri, projection, selection, selectionArgs, sortOrder);
            //Cursor cursor=managedQuery(uri, projection, selection, selectionArgs, sortOrder);
            Cursor phonecur = null;

            int count = 0;
            while (cursor.moveToNext()){

                // 取得联系人名字
                int nameFieldColumnIndex = cursor.getColumnIndex(android.provider.ContactsContract.PhoneLookup.DISPLAY_NAME);
                String name = cursor.getString(nameFieldColumnIndex);
                // 取得联系人ID
                String contactId = cursor.getString(cursor.getColumnIndex(android.provider.ContactsContract.Contacts._ID));
                //phonecur = managedQuery(android.provider.ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, android.provider.ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = "  + contactId, null, null);
                phonecur = contentResolver.query(android.provider.ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, android.provider.ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + contactId, null, null);
                // 取得电话号码(可能存在多个号码)
                while (phonecur.moveToNext()){
                    String strPhoneNumber = phonecur.getString(phonecur.getColumnIndex(android.provider.ContactsContract.CommonDataKinds.Phone.NUMBER));
                    strPhoneNumber = strPhoneNumber.replace("-", "").replace("+86","").replace(" ","");
                    if(strPhoneNumber.length()==11) {
                        //allContacts.add(new ContactDetail(contactId, "wallimn", "13801380000"));
                        allContacts.add(new ContactDetail(contactId, name, strPhoneNumber));
                    }

                }
                count++;
                phonecur.close();
                phonecur = null;
                //if(count>20)break;
            }

            cursor.close();
            Message loaded=new Message();
            loaded.what=UPDATE_LIST;
            messageHandler.sendMessage(loaded);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        allContacts.clear();
    }

    /**
     * 联系人信息适配器
     */
    public static class ContactAdapter extends BaseAdapter{

        private List<ContactDetail> list;
        private Context context;

        public  List<ContactDetail> getList(){
            return this.list;
        }
        /**
         * 构造函数,传入list参数,避免代码耦合
         * @param list
         */
        public ContactAdapter(Context context,List<ContactDetail> list){
            this.list = list;
            this.context = context;
        }
        @Override
        public int getCount() {
            return list.size();
        }

        @Override
        public Object getItem(int position) {
            return list.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ContactDetail cd = list.get(position);
            final int index = position;
            if(convertView == null){
                convertView = LayoutInflater.from(context).inflate(R.layout.person_row, null);
            }else{
                ;
            }
            ((TextView)convertView.findViewById(R.id.contact_id)).setText(cd.id);
            ((TextView)convertView.findViewById(R.id.contact_name)).setText(cd.name);
            ((TextView)convertView.findViewById(R.id.contact_mobile)).setText(cd.mobile);
            ((TextView)convertView.findViewById(R.id.contact_title)).setText(cd.title);
            ((TextView)convertView.findViewById(R.id.contact_remark1)).setText(cd.remark1);
            ((CheckBox) convertView.findViewById(R.id.contact_checbox)).setChecked(cd.checked);
            return convertView;
        }

    }
}
  • 大小: 114.3 KB
分享到:
评论

相关推荐

    android listview 里面使用checkbox

    在Android开发中,ListView是一种常用的组件,用于展示可滚动的多行数据列表。当需要在ListView的每一项中加入复选框(Checkbox)时,这通常涉及到自定义Adapter和处理复选状态的逻辑。以下是对这个主题的详细阐述:...

    android ListView+CheckBox实现单选

    在Android开发中,ListView是一种常用的组件,用于展示可滚动的列表数据。当需要在列表项中添加选择功能时,我们通常会结合使用ListView与CheckBox。本篇将详细讲解如何利用这两种组件实现ListView中的单选功能。 ...

    android之listview和checkbox

    在Android开发中,ListView是一种非常常见的控件,用于展示大量数据列表。它的高效性和可滚动性使得它在各种场景下都能发挥重要作用。本教程将深入探讨如何在ListView中集成CheckBox,以便用户可以选择列表中的多项...

    【Android】ListView与CheckBox的完美结合

    在Android开发中,ListView是一种常用的组件,用于展示大量的列表数据。它通过滚动的方式节省屏幕空间,使得用户可以浏览和操作众多条目。本教程将深入探讨如何将ListView与CheckBox结合,实现一个CheckList,允许...

    实现ListView中CheckBox的选中和选中项的记录

    在Android开发中,ListView是一种常用的组件,用于展示大量的列表数据。在某些应用场景,如购物车功能,我们可能需要在ListView的每一行中添加一个CheckBox,让用户可以选择他们感兴趣的商品。本篇将详细介绍如何...

    Android中ListView结合CheckBox获取选中项.rar

    在Android开发中,ListView是一种常用的组件,用于展示大量的列表数据。当需要在列表项中加入可选择的功能时,我们通常会结合使用CheckBox。本示例"Android中ListView结合CheckBox获取选中项.rar"旨在教授如何在...

    android listview ScrollView冲突 listview checkbox

    在Android开发中,ListView与ScrollView的使用经常会产生冲突,因为两者都是用来展示多行数据的控件,但它们的工作机制有所不同。ListView通过复用Item视图来提高性能,而ScrollView则将所有子视图一次性加载到内存...

    ListView添加CheckBox复选框

    在Android开发中,ListView是一种常用的控件,用于展示大量数据列表。为了增加用户交互性,我们经常会在ListView的每一项中添加CheckBox,这样用户就可以进行多选操作。本篇文章将详细讲解如何在ListView中实现...

    Android ListView+checkbox 实现批量删除

    在Android开发中,ListView是常用的数据展示控件,它可以高效地显示大量数据并支持滚动操作。在实际应用中,我们经常需要实现一个功能,让用户能够选择ListView中的多个条目进行批量删除,这正是"Android ListView+...

    解决ListView嵌套CheckBox滑动时选中状态错乱

    在Android开发中,ListView是常用的数据展示控件,它可以有效地展示大量数据并实现滚动效果。然而,当ListView内部嵌套CheckBox等可交互组件时,常常会遇到一些问题,特别是滑动过程中选中状态错乱的现象。这个问题...

    listview中添加CheckBox的完美实现

    但是在实际开发中,我们经常需要在 ListView 中添加 CheckBox,以便用户可以选择某些项目。然而,添加 CheckBox 到 ListView 中并不是一件简单的事情,因为它需要解决事件冲突和复用错误的问题。 在本文中,我们将...

    Android完美解决ListView复用导致的Checkbox状态混乱问题

    在Android开发中,ListView是常用的一种控件,用于展示大量数据列表。然而,ListView的复用机制有时会导致一些问题,特别是在涉及复选框(Checkbox)的状态管理时。本篇文章将详细探讨这个问题,并提供一个完美的...

    android listview+checkbox实现多选

    在Android开发中,ListView是常用的一种控件,用于展示大量数据列表。在许多场景下,我们需要在ListView中加入复选框(Checkbox),实现多选功能,例如用户可以选择多个项目进行操作。本文将详细介绍如何在Android中...

    Android中使用ListView和CheckBox实现购物车多选功能

    在Android开发中,ListView是常用的一种控件,用于展示大量数据列表。而CheckBox则是实现用户交互,特别是多选操作的关键组件。在这个应用中,我们利用ListView结合CheckBox来模拟淘宝购物车的功能,允许用户进行...

    Android ListView CheckBox

    在Android开发中,ListView是一种常用的视图组件,用于展示大量数据列表。CheckBox则是用来实现复选功能,常常与ListView结合,以实现用户对列表项的多选操作。本篇文章将详细探讨如何在Android中实现一个具有多选、...

    android listView含CheckBox、Button、EditText

    在Android开发中,ListView是一种非常常见的控件,用于展示大量数据列表。在设计用户界面时,我们有时需要在ListView的每一项中包含多种交互元素,如CheckBox、Button和EditText,以提供更丰富的功能。本篇将详细...

    android -- listview与checkbox联用

    在Android开发中,ListView是常用的一种控件,用于展示大量数据列表。然而,当需要在ListView的每一项中加入可勾选的Checkbox时,开发者往往会遇到一些问题,比如CheckBox的状态控制困难,点击事件冲突等。本教程将...

    listview中的checkbox的几种处理方式

    在Android开发中,ListView是一种常用的组件,用于展示大量的列表数据。在某些场景下,我们可能需要在每个ListView的项中嵌入一个Checkbox,以便用户可以选择多个条目。本篇文章将详细探讨三种处理ListView中...

    Android ListView 带 CheckBox(全选,反选,全不选)

    在Android开发中,ListView是一种常用的组件,用于展示大量的列表数据。在实际应用中,我们经常需要在ListView的每个项中添加CheckBox,以便用户可以进行多选操作,如选择联系人、选择任务等。本篇文章将深入讲解...

Global site tag (gtag.js) - Google Analytics