上文我们谈过通话记录页面的界面显示
下面我们继续通话记录进行一个引申---通话详情界面的跳转过程
在CallLogAdapter中,有一个方法,在该方法中
private void findAndCacheViews(View view) {
// Get the views to bind to.
CallLogListItemViews views =
CallLogListItemViews.fromView(view);
views.primaryActionView.setOnClickListener(mPrimaryActionListener);
views.secondaryActionView.setOnClickListener(mSecondaryActionListener);
view.setTag(views);
}
为view设置了一些点击事件,这样就可以点击listView中的某一项的具体某个位置来触发
那么什么时候调用该方法呢?在代码newStandAloneView等三个方法中,在初始化了布局文件后,就会调用该方法为界面绑定点击事件。
下面我们再次看看布局文件,对应一下primaryAction 和 secondaryAction 是哪块区域
图1 通话记录项
通过查看布局文件call_log_list_item.xml后,我们发现,上图红色标注的地方就是上文提到的primaryAction区域,而蓝色标注的区域就是secondaryAction区域。
好,尽然我们已经看过各自代表的区域了,是不是应该想着看看点击后进入什么神秘的地方了呢?
继续跟进
private
final View.OnClickListener mPrimaryActionListener = new
View.OnClickListener() {
@Override
public void onClick(View view) {
IntentProvider intentProvider = (IntentProvider) view.getTag();
if (intentProvider != null) {
mContext.startActivity(intentProvider.getIntent(mContext));
}
}
};
private
final View.OnClickListener mSecondaryActionListener= new
View.OnClickListener() {
@Override
public void onClick(View view) {
IntentProvider intentProvider = (IntentProvider)
view.getTag();
if (intentProvider != null) {
mContext.startActivity(intentProvider.getIntent(mContext));
}
}
};
不好,二者完全一样啊! 怎么跳的呢?有点小复杂,汗~
别急,在监听器中,我们发现了如下的语句
IntentProvider intentProvider = (IntentProvider)
view.getTag();
view.getTag()而我们点击的时候view是secondActionView或者是primaryActionView,那么必定有方法为期绑定了Tag,继续跟进…
在
private void bindView(View view, Cursor c, int count)
方法中,我们发现了如下的线索
this,
c.getPosition(), c.getLong(CallLogQuery.ID), count));
views.secondaryActionView.setTag(IntentProvider.getPlayVoicemailIntentProvider(
rowId, voicemailUri));
views.secondaryActionView.setTag(IntentProvider.getReturnCallIntentProvider(number));
哈哈,就是这了,
为primaryActionView和secondaryActionView设置了一个Tag,
好我们仅以第三句为例(每一句实际操作都是类似的,第三句的代码稍短些),看看其是怎么进行操作的。
IntentProvider的getReturnCallIntentProvider方法内容如下:
public static IntentProvider
getReturnCallIntentProvider(final String number) {
return new IntentProvider() {
@Override
public Intent getIntent(Context context) {
Uri uri;
if (PhoneNumberUtils.isUriNumber(number)) {
uri = Uri.fromParts("sip", number, null);
} else {
uri = Uri.fromParts("tel", number, null);
}
return new Intent(Intent.ACTION_CALL_PRIVILEGED, uri);
}
};
}
在这里关键部位是返回值
首先看方法头public static IntentProvider
getReturnCallIntentProvider(final String number)
原来我们要返回的是一个IntentProvider,
方法体里面主要就是构造了一个匿名内部类,并将该类的一个对象返回给调用者,由于IntentProvider是抽象类,所以在内名内部类中实现了其抽象方法getIntent,在调用的过程中,使用类的向上转型,通过父类对象调用子类的方法,
即
IntentProvider intentProvider = (IntentProvider)
view.getTag();
intentProvider.getIntent(mContext)
两句,如果这对向上转型有不明白的,请查阅相关的资料,本文在不赘述。
通过在bindView中为PrimaryActionView和SecondActionView设置Tag,设定了点击后跳转的方向。
当点击secondActionView即电话图标,已经没有什么好说的了,跳到通话页面,下面主要进行讲解的是按PrimaryActionView时的跳转。
通过代码可知,调转到CallDetailActivity(为什么跳转到这个页面请查看IntentProvider类的getCallDetailIntentProvider方法)
至于CallDetailActivity没有什么难点,写法和原来的方式一样,在此就不多浪费大家的时间了。