【Contacts】联系人界面添加联系人统计项

题记

工作需要在Android6.0的Contacts(联系人模块添加联系人统计项),这里分享下所用的一些知识及解决方案。

知识点

  1. 如何添加组件至ListView末尾
  2. 如何监听ContentProvider数据库变化
  3. 如何进行统计联系人数量

首先介绍下整个设计的思路。

由左图效果变为右图的效果(请忽略建立的3个联系人),联系人页面的底部添加一项TextView来显示联系人统计项。随着新建联系人、删除联系人、合并联系人、拆分联系人等操作,统计项会随时更新。
下面根据知识点来进行介绍:

1. 如何添加组件至ListView末尾
如上图我们需要将统计项添加到联系人页面的最后一项(模仿ios);也就是需要将统计项添加至ListView末尾,好在Listview组件提供了这样的接口:listview.addFooterView();
查看Android API:

void addFooterView(View v)
Add a fixed view to appear at the bottom of the list.

public void addFooterView (View v)

Added in API level 1 Add a fixed view to appear at the bottom of the
list. If addFooterView is called more than once, the views will appear
in the order they were added. Views added using this call can take
focus if they want.

Note: When first introduced, this method could only be called before
setting the adapter with setAdapter(ListAdapter). Starting with
KITKAT, this method may be called at any time. If the ListView’s
adapter does not extend HeaderViewListAdapter, it will be wrapped with
a supporting instance of WrapperListAdapter.

Parameters v The view to add.

使用该该方法将统计项添加至ListView项,下面为代码实现部分

// 显示联系人数量view
// 获取统计项view,使用xml布局进行定义
View mFootView = ((LayoutInflater) getContext().getSystemService(
        Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.contact_count, null, false);
// 显示联系人数量的TextView
mCountTextView = (TextView)mFootView.findViewById(R.id.contact_cout);
// 将统计项View添加至ListView
mListView.addFooterView(mFootView);

下面是contact_count.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:gravity="center_horizontal"
    android:orientation="vertical"
    android:padding="3dp" >

    <TextView
        android:id="@+id/contact_cout"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:layout_marginBottom="10dp"
        android:gravity="center"
        android:padding="5dp" />

</LinearLayout>

2. 如何监听ContentProvider数据库变化
要实现新建联系人、删除联系人、合并联系人、拆分联系人等操作后,实时进行TextView的更新;也就是实时监测数据的变化–类似设计模式中的Observer模式;
查询资料:Android对于ContentProvider类型的数据,系统提供了监听的方案:ContentObserver
ContentObserver详细使用方法可参见如下博客:

http://emowuyi.iteye.com/blog/1323640

使用ContentObserver进行监听数据库变化,可以分为3步

  • 创建我们特定的ContentObserver派生类,必须重载父类构造方法,必须重载onChange()方法去处理回调后的功能实现
    /**
     * ContentObserver监听数据变化类
     */
    class ContactContent extends ContentObserver {

        private Cursor cursor = null;

        public ContactContent(Handler handler) {
            super(handler);
            // TODO Auto-generated constructor stub
        }

        @Override
        public void onChange(boolean selfChange) {
            // TODO Auto-generated method stub
            super.onChange(selfChange);
            // 数据库发生变化时,更新mCountTextView中的数量
            refreshContactCount();
        }

    }
  • 利用context.getContentResolover()获得ContentResolove对象,接着调用registerContentObserver()方法去注册内容观察者:
    public final void registerContentObserver(Uri uri, boolean notifyForDescendents, ContentObserver observer)
    这里需要注意registerContentObserver的三个参数:
    第一个uri:为我们需要检测的数据库(表);本例中是检测联系人raw_contacts表
    第二个notifyForDescendents:为true时可以检测数据库的变化
    第三个observer:ContentObserver的派生类实例,数据发生变化后的进行处理功能完成。
private ContactContent mContactContent = new ContactContent(new Handler());

// 注册监听联系人数据库    getContext().getContentResolver().registerContentObserver(RawContacts.CONTENT_URI, true, mContactContent);
  • 当然注册过后,退出程序时一定要进行解注册,如果不是这样,反复进入应用会引起内存泄露;世界万物有生即有灭。
    public final voidunregisterContentObserver(ContentObserver observer)
    取消对给定URI的观察。
    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        getContext().getContentResolver().unregisterContentObserver(mContactContent);
    }

3. 如何进行统计联系人数量
获取联系人信息采用ContentResolver进行对ContentProvider的操作:
详细可见之前的一篇总结:

http://blog.csdn.net/uestcyms/article/details/49149633

1、获取ContentResolver,然后再根据数据库的一些判定条件获取到需要操作的数据库的游标cursor

 ContentResolver cr = getContext().getContentResolver();
 Cursor cursor = cr.query(RawContacts.CONTENT_URI, new String[] {
        RawContacts.CONTACT_ID
        }, RawContacts.DELETED
        + " = 0", null, null);

2、根据cursor来进行后续的操作–计算联系人的数量
这里值得提出来的是使用原生合并、拆分联系人操作后,合并的时候是将raw_contacts 中的两项中的RawContacts.CONTACT_ID这一项设置为相同,拆分时再将之分离。也就是我们统计联系人数量时需要计算RawContacts.CONTACT_ID这一列的数量减去重复的行数。

        if (cursor != null) {
            List<String> mList = new ArrayList<String>();
            while(cursor.moveToNext()){
// 如果重复则不添加至mList,保证mList中无重复。               if(!mList.contains(cursor.getString(cursor.getColumnIndex(RawContacts.CONTACT_ID)))){
                    mList.add(cursor.getString(cursor.getColumnIndex(RawContacts.CONTACT_ID)));
                }
            }
            mCountTextView.setText(mList.size()+getString(R.string.contact_count));
        }

后记

很久没有更新博客,最近很忙,工作和生活,无论生活还是工作,不要太在意别人的看法,有时自己认为很重的东西,在别人眼中很轻。所以要轻松的活着。

今天推荐大家一首五月天的歌曲《时光机》–我愿意 付出所有来换一个时光机;
如果拥有一个时光机,大家想回到什么时候呢?想改变之前的某个决定吗?想更加的勇敢吗?

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值