美文网首页
联系人详情Recent列表浅析

联系人详情Recent列表浅析

作者: sp_zijing | 来源:发表于2017-11-15 15:19 被阅读0次
需求:修改联系人详情界面中的CallLog记录,使其能够指示该呼叫产生于哪一张SIM卡。
原生效果.png

在Android M中,联系人详情统一到了QuickContactActivity.java这个类中。详情界面涉及到联系人的信息,Recent列表还包含CallLog,SMS,Calendar事件信息。

CallLog,SMS,Calendar事件的加载显示流程大同小异,因为本文需求是修改CallLog的图标,因此以CallLog为例。

这些数据肯定是要在Activity启动时加载的,我们在onResume中找到了startInteractionLoaders这么个方法,部分实现如下:

getLoaderManager().initLoader( LOADER_CALL_LOG_ID, phonesExtraBundle, mLoaderInteractionsCallbacks);

启动了一个Loader,ID为LOADER_CALL_LOG_ID,回调MLoaderInteractionsCallbacks,没啥说的,去回调中看看再说:

loader = new CallLogInteractionsLoader(
                                    QuickContactActivity.this,
                                    args.getStringArray(KEY_LOADER_EXTRA_PHONES),
                                    MAX_CALL_LOG_RETRIEVE);

好了,这里找到了Loader的具体实现类。CallLogInteractionsLoader的后两个参数分别是电话号码和查询的最大条数。我们很关心这个Loader到底会加载哪些数据,因为要实现需求,我们需要知道呼叫记录产生的SIM卡。看看它的loadInBackground的实现:

for (String number : mPhoneNumbers) {
            interactions.addAll(getCallLogInteractions(number));
}

继续查看getCallLogInteractions实现:

final Cursor cursor = getContext().getContentResolver().query(uri, null, null, null,
                orderByAndLimit);

query的参数都是null。Good!要啥有啥!

我们回过头来,继续看Loader的onLoadFinished回调:

mRecentLoaderResults.put(loader.getId(), data);
if (isAllRecentDataLoaded()) {
       bindRecentData();
}

嗯,把数据存储在mRecentLoaderResults中,然后bindRecentData,准备绑定view啦!

mRecentDataTask = new AsyncTask<Void, Void, Void>() {
            @Override
            protected Void doInBackground(Void... params) {
                                     …………
                // Wrap each interaction in its own list so that an icon is displayed for each entry
                for (Entry contactInteraction : contactInteractionsToEntries(allInteractions)) {
                    List<Entry> entryListWrapper = new ArrayList<>(1);
                    entryListWrapper.add(contactInteraction);
                    interactionsWrapper.add(entryListWrapper);
                }

                Trace.endSection();
                return null;
            }

            @Override
            protected void onPostExecute(Void aVoid) {
                super.onPostExecute(aVoid);
                Trace.beginSection("initialize recents card");

                if (allInteractions.size() > 0) {
                    mRecentCard.initialize(interactionsWrapper,
                    /* numInitialVisibleEntries = */ MIN_NUM_COLLAPSED_RECENT_ENTRIES_SHOWN,
                    /* isExpanded = */ mRecentCard.isExpanded(), /* isAlwaysExpanded = */ false,
                            mExpandingEntryCardViewListener, mScroller);
                    mRecentCard.setVisibility(View.VISIBLE);
                }
                                    …………
            }
        };

在bindRecentData中是用Asynctask先对查找结果按日期排序了,将排序结果从contactInteractions转换成了Entry,存入interactionWrapper中,然后在onPostExecute中来初始化mRecentCard。初始话的工作无非就是各种赋初值,然后设置监听啊等。在上面新建Loader实力的时候,是传入了一个context的,使用这个context创建了一个LayoutInflater,这里才是view真正产生的地方,代码如下:

entryViewList.add(createEntryView(layoutInflater, entryList.get(0), /* showIcon = */ View.VISIBLE));

createEntryView这个方法比较长,都是view里的内容的设置,包括icon,header等等。这里猜测我们要改的就是Icon了。为了验证,我们用HierarchyViewer来查看一下:


ExpandingEntryCardView.png

嗯,没毛病,看来修改icon的资源文件就行了。来看看开始是怎么样的:

        final ImageView icon = (ImageView) view.findViewById(R.id.icon);
        icon.setVisibility(iconVisibility);
        if (entry.getIcon() != null) {
            icon.setImageDrawable(entry.getIcon());
        }

是从entry获取的。这个Entry是ExpandingEntryCardView的一个内部类。这里我们又要回头去看看这个entry是何时用了啥资源创建出来的了。前文在bindRecentData的时候有提到过从contactInteractions转为Entry,没有细看,这里我们要看看他的实现了:

private List<Entry> contactInteractionsToEntries(List<ContactInteraction> interactions) {
        final List<Entry> entries = new ArrayList<>();
        for (ContactInteraction interaction : interactions) {
            if (interaction == null) {
                continue;
            }
            entries.add(new Entry(/* id = */ -1,
                    interaction.getIcon(this),
                    interaction.getViewHeader(this),
                    interaction.getViewBody(this),
                    interaction.getBodyIcon(this),
                    interaction.getViewFooter(this),
                    interaction.getFooterIcon(this),
                    interaction.getContentDescription(this),
                    interaction.getIntent(),
                    /* alternateIcon = */ null,
                    /* alternateIntent = */ null,
                    /* alternateContentDescription = */ null,
                    /* shouldApplyColor = */ true,
                    /* isEditable = */ false,
                    /* EntryContextMenuInfo = */ null,
                    /* thirdIcon = */ null,
                    /* thirdIntent = */ null,
                    /* thirdContentDescription = */ null,
                    /* thirdAction = */ Entry.ACTION_NONE,
                    /* thirdActionExtras = */ null,
                    interaction.getIconResourceId()));
        }
        return entries;
    }

发现就是重新把数据换个类存放而已。这里Interaction是接口,CallLog,SMS,Calendar有各自的实现,CallLogInteraction的getIcon实现如下:
return context.getResources().getDrawable(CALL_LOG_ICON_RES);
如此直白。依据需求我们根据SIM卡号设置对应资源文件就行了。

        if (mValues.getAsInteger(Calls.SLOT_ID) == 0)
            return context.getResources().getDrawable(CALL_LOG_ICON_RES_SIM1);
        else
            return context.getResources().getDrawable(CALL_LOG_ICON_RES_SIM2);
修改后效果.png

相关文章

  • 联系人详情Recent列表浅析

    在Android M中,联系人详情统一到了QuickContactActivity.java这个类中。详情界面涉及...

  • 获取系统通讯录

    AddressBookUI.framework 提供了联系人列表界面, 联系人详情界面, 添加联系人界面等。一般用...

  • 通讯录 - (ContactsUI、Contacts)

    AddressBookUI.framework 提供了联系人列表界面、联系人详情界面、添加联系人界面等一般用于选择...

  • 通讯录ContactsUI

    AddressBookUI.framework提供了联系人列表界面 联系人详情界面 添加联系人界面等一般用于选择联...

  • iOS最新获取手机通讯录方式

    一、iOS 9 以前的通讯录框架 AddressBookUI框架:提供了联系人列表界面、联系人详情界面、添加联系人...

  • iOS端获取手机通讯录手机号码

    一、iOS 9 以前的通讯录框架 AddressBookUI框架:提供了联系人列表界面、联系人详情界面、添加联系人...

  • iOS9以后获取手机通讯录

    一、iOS 9 以前的通讯录框架AddressBookUI框架:提供了联系人列表界面、联系人详情界面、添加联系人界...

  • 09、CoreData版的联系人列表

    咱们的这个联系人列表可以对通讯录中的人进行添加联系人操作,并且可以点击某个联系人,进入详情界面,对联系人的个人信息...

  • ImportError: cannot import name

    具体错误详情 Traceback (most recent call last):File "D:/pycharm...

  • R7.13

    working!!!! Done Master列表 瞄列表 竞标列表 Doing 问答详情 master详情 选择...

网友评论

      本文标题:联系人详情Recent列表浅析

      本文链接:https://www.haomeiwen.com/subject/hczcvxtx.html