在Android4.0中Contacts通话记录界面剖析(源码)

看完了拨号盘界面的实现后,大家可能会感觉到,挺简单的,没什么复杂的,只是在onCreateView方法中加载了一个layout,然后就全都看到了,so easy!

那么,我们接下来就分享一下稍微复杂一点的CallLog界面,希望大家看完后,依然会如此说!

   DialtactsActivity中通话记录对应的FragmentCallLogFragment

下面我们先来看看通话记录的默认显示,下图1

在Android4.0中Contacts通话记录界面剖析(源码)

 

                 1  通话记录页面

   咋一看,该页面分为两部分,tab titlelist列表页面

   Tabtitle 就不再复说了,与上文中的拨号界面的实现方式完全相同,现主要描述通话记录的list页面,实际上该页面还会出现通话记录为空的界面等。

通话记录页面的实现

现在我们直接来看onCreateView方法

在该方法第一句

   View view = inflater.inflate(R.layout.call_log_fragment, container, false);

跟进call_log_fragment.xml

发现

<ListView android:id="@android:id/list"

            android:layout_width="match_parent"

            android:layout_height="match_parent"

            android:fadingEdge="none"

            android:scrollbarStyle="outsideOverlay"

            android:divider="@null"

  />

估计该listView就是要显示的列表

跟进代码

奇怪了,CallLogFragment代码中怎么就没有调用list的呢?

如果这条线断了,就不知道往下该咋弄了啊! ~

原来是这样子的,CallLogFragment继承自ListFragment而在ListFragment中的ensureList方法中进行了初始化,具体的语句如下:

View rawListView = root.findViewById(android.R.id.list); 

mList = (ListView)rawListView;

rawListView获得的list的名字是android.R.id.list,而我们的布局文件中list的名字是@android:id/list,没错了吧。

而在我们的CallLogFragment中只要调用getListView即可获得listView

为了避免您的怀疑,我们在看一下ListFragmentgetListView方法:

public ListView getListView() {

        ensureList();

        return mList;

 }

既然找到了list,接下来我们要看看数据的绑定了,

一提到数据的绑定,立即就会想到Adapter,下面我们看看Android源码是怎么写的

onViewCreated方法中,我发现了如下的几句话

String currentCountryIso = ContactsUtils.getCurrentCountryIso(getActivity());

mAdapter = new CallLogAdapter(getActivity(), this, new ContactInfoHelper(getActivity()

, currentCountryIso), mVoiceMailNumber);

setListAdapter(mAdapter);

第二句创建了一个CallLogAdapter对象,然后调用setListAdapter方法,将CallLogAdapter对象设置过去,

不用说setListAdapter方法肯定是ListFragment的方法,看代码

public void setListAdapter(ListAdapter adapter) {

        boolean hadAdapter = mAdapter != null;

        mAdapter = adapter;

        if (mList != null) {

            mList.setAdapter(adapter);

            if (!mListShown && !hadAdapter) {

                // The list was hidden, and previously didn't have an

                // adapter.  It is now time to show it.

                setListShown(true, getView().getWindowToken() != null);

            }

        }

}

代码中对我们来说最重要的一句 

 mList.setAdapter(adapter);

mList对应于我们布局文件中的list,没错了吧,看样一切的秘密都在这个adapter中了,继续跟进adapter

Adapter怎么会没有getView呢?

我们看CallLogAdapter的父类,GroupingListAdapter,在该方法中有getView方法,

public View getView(int position, View convertView, ViewGroup parent) {

                          

        if (view == null) {

            switch (mPositionMetadata.itemType) {

                case ITEM_TYPE_STANDALONE:

                    view = newStandAloneView(mContext, parent);

                    break;

                case ITEM_TYPE_GROUP_HEADER:

                    view = newGroupView(mContext, parent);

                    break;

                case ITEM_TYPE_IN_GROUP:

                    view = newChildView(mContext, parent);

                    break;

            }

        }

      

        return view;

    }

原来是调用了newStandAloneViewnewGroupViewnewChildView方法,来创建view

那么我们接下来继续回到CallLogAdapter中查看上述三个方法所加载的布局文件

call_log_list_item.xml

呵呵,一看该布局,不会有错了,就是该list的分项

 

Ok,简单吧

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值