`

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
分享到:
评论

相关推荐

    基于java的的个人博客网站的设计与实现设计与实现.docx

    基于java的的个人博客网站的设计与实现设计与实现.docx

    基于java的技术大健康综合咨询问诊平台的设计与实现.docx

    基于java的技术大健康综合咨询问诊平台的设计与实现.docx

    java-ssm+vue小型企业办公自动化系统实现源码(项目源码-说明文档)

    系统可以提供信息显示和相应服务,其管理员管理部门经理,管理总经理,管理员工和员工留言以及员工工资,管理内部邮件,管理审批流程,管理离职申请。部门经理给员工发放工资,审核并回复员工留言,管理员工工资,审核员工的离职申请信息,查询和下载内部邮件以及审批流程。总经理查询下载内部邮件和审批流程,审核员工离职申请,查询员工工资,查询员工和部门经理。员工发布留言,发布内部邮件,发布离职申请,查询通知公告和审批流程,查看员工本人工资。 项目关键技术 开发工具:IDEA 、Eclipse 编程语言: Java 数据库: MySQL5.7+ 后端技术:ssm 前端技术:Vue 关键技术:springboot、SSM、vue、MYSQL、MAVEN 数据库工具:Navicat、SQLyog

    基于java的网上办公自动化系统设计与实现.docx

    基于java的网上办公自动化系统设计与实现.docx

    2019优益C x 易烊千玺微博营销案结案报告.pptx

    2019优益C x 易烊千玺微博营销案结案报告.pptx

    led-tcp-maste资源

    led-tcp-maste资源

    金士顿U盘微博营销活动策划方案.ppt

    金士顿U盘微博营销活动策划方案.ppt

    chipup芯昇XS2180-PoE芯片说明,详细版

    chipup芯昇XS2180-PoE芯片说明,详细版

    #_ssm_105_mysql_学生比赛指导管理系统_.zip

    均包含代码,文章,部分项目包含ppt

    基于java的中小企业人力资源管理系统的设计与实现.docx

    基于java的中小企业人力资源管理系统的设计与实现.docx

    C语言入门教程.zip

    【c语言入门】 静态库、动态链接库、include、makefile、io、文件操作函数、管道原理及应用、简单的数据结构

    基于java的在线学习系统设计与实现系统设计与实现.docx

    基于java的在线学习系统设计与实现系统设计与实现.docx

    蓝桥杯第十四届程序C组试题B自行整理(包括答案)

    主要对蓝桥杯第十四届程序C组试题B进行代码编写

    ASP.NET+SQL通用作业批改系统设计(源代码+论文).zip

    1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。

    智能制造建模与仿真技术及其发展趋势

    本文详细介绍了智能制造领域里的建模与仿真技术的概念和特点,包括它们的基本定义、最新特点,如集成化、模块化、层次化、跨学科化、计算高速化以及人工智能化的趋势,并阐述了其关键技术,还提供了多个典型案例分析。另外,探讨了未来建模仿真技术在智能制造背景下的发展走向,特别是在实时仿真、云端建模与仿真和下一代数字模型方面的前景。 适用人群:智能制造相关的行业从业者、研究学者或者具有一定工程基础的学生。 使用场景及目标:适用于希望深入理解建模和仿真如何应用于智能生产的专业人士,并希望通过该领域的技术进步提升自己的业务水平和科研创新能力。 阅读推荐:此资源非常适合那些渴望获得有关智能制造中各种建模与仿真应用场景的知识的人群。它提供了从理论知识到实际工业项目的实例分析,涵盖了广泛的视角。

    EfficientFormer实战:使用EfficientFormerV2实现图像分类任务

    EfficientFormerV2是一种通过重新思考ViT设计选择和引入细粒度联合搜索策略而开发出的新型移动视觉骨干网络。它结合了卷积和变换器的优势,通过一系列高效的设计改进和搜索方法,实现了在移动设备上既轻又快且保持高性能的目标。这一成果为在资源受限的硬件上有效部署视觉变换器模型提供了新的思路 原文链接:https://blog.csdn.net/hhhhhhhhhhwwwwwwwwww/article/details/142367223

    一套通过人脸识别遗传病的机器学习系统.zip(毕设&课设&实训&大作业&竞赛&项目)

    项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用

    基于java的基于分类算法的学业警示预测系统设计与实现.docx

    基于java的基于分类算法的学业警示预测系统设计与实现.docx

    基于TensorRT实现轻量级语义分割的C++程序源码+文档说明+模型.zip

    基于TensorRT实现轻量级语义分割的C++程序源码+文档说明+模型.zip基于TensorRT实现轻量级语义分割的C++程序源码+文档说明+模型.zip基于TensorRT实现轻量级语义分割的C++程序源码+文档说明+模型.zip 个人大四的毕业设计、课程设计、作业、经导师指导并认可通过的高分设计项目,评审平均分达96.5分。主要针对计算机相关专业的正在做毕设的学生和需要项目实战练习的学习者,也可作为课程设计、期末大作业。 [资源说明] 不懂运行,下载完可以私聊问,可远程教学 该资源内项目源码是个人的毕设或者课设、作业,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96.5分,放心下载使用! 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),供学习参考。

    大数据之机器学习推荐系统.zip(毕设&课设&实训&大作业&竞赛&项目)

    项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用

Global site tag (gtag.js) - Google Analytics