1.4,界面刷新
在此介绍2中复杂界面的刷新过程, ListView和RecyclerView。
4.1 ListView
在界面刷新时,会调用View的onLayout方法,对于ListView,就会调用父类AbsListView的onLayout方法,中间的过程以及种种方法在此不论述了,流程图如下,
在AbsListView的obtainView方法中,会调用ListAdapter对象的getView方法,
final View child = mAdapter.getView(position, scrapView, this);
4.2 RecyclerView
同样的, 在界面刷新时,会调用RecyclerView的onLayout方法,调用流程图如下,
getItemCount/onCreateViewHolder/onBindViewHolder这三个方法都是Adapter的抽象方法,因此需要子类实现。
通话记录是使用RecyclerView实现的,因此,主要论述onCreateViewHolder和onBindViewHolder方法。
4.3 onCreateViewHolder
CallLogAdapter的onCreateViewHolder方法如下,
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == VIEW_TYPE_SHOW_CALL_HISTORY_LIST_ITEM) {
return ShowCallHistoryViewHolder.create(mContext, parent);
} else if (viewType == VIEW_TYPE_VOICEMAIL_PROMO_CARD) {
return createVoicemailPromoCardViewHolder(parent);
}
return createCallLogEntryViewHolder(parent);
}
createCallLogEntryViewHolder的方法如下,
private ViewHolder createCallLogEntryViewHolder(ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(mContext);
View view = inflater.inflate(R.layout.call_log_list_item, parent, false);
CallLogListItemViewHolder viewHolder = CallLogListItemViewHolder.create(
view, mContext, mExpandCollapseListener, mTelecomCallLogCache,
mCallLogListItemHelper, mVoicemailPlaybackPresenter);
viewHolder.callLogEntryView.setTag(viewHolder);
viewHolder.callLogEntryView.setAccessibilityDelegate(mAccessibilityDelegate);
viewHolder.primaryActionView.setOnCreateContextMenuListener(mOnCreateContextMenuListener);
viewHolder.primaryActionView.setTag(viewHolder);
return viewHolder;
}
由此,一条通话记录就对应一个CallLogListItemViewHolder对象。
4.4.onBindViewHolder
CallLogAdapter的onBindViewHolder方法如下,
case VIEW_TYPE_SHOW_CALL_HISTORY_LIST_ITEM:
break;
case VIEW_TYPE_VOICEMAIL_PROMO_CARD:
bindVoicemailPromoCardViewHolder(viewHolder);
break;
default:
bindCallLogListViewHolder(viewHolder, position);
break;
参数中的viewHolder就是CallLogAdapter的onCreateViewHolder方法中构造的CallLogListItemViewHolder对象。
方法会调用bindCallLogListViewHolder方法加载每条通话记录的信息, bindCallLogListViewHolder方法的主要逻辑如下,
1,获取通话记录组中的第一个Cursor以及该组中的通话记录条数。
Cursor c = (Cursor) getItem(position);
if (c == null) {
return;
}
int count = getGroupSize(position);
2,依次将号码等信息封装在ContactInfo, PhoneCallDetails以及CallLogListItemViewHolder类中。
3,控制是否显示分组,调用CallLogListItemViewHolder的showActions()函数是否显示新建联系人等信息(根据ContactInfo来决定)。
4,调用CallLogListItemViewHolder的setPhoto函数显示图标以及姓名等信息。
5,PhoneCallDetailsViews详细的显示PhoneCallDetails中的通话记录信息(通话时间以及归属地等等),并且PhoneCallDetailsViews是包含于CallLogListItemViewHolder中的。