Contacts拨号盘源码学习
- 1、Contacts拨号盘打开的是类DialerPhoneActivity的实例,在launcher中通过Intent切换。
查找方法:通过查看launcher中出现的图片hotseat_phone_normal.png,找到hotseat_phone按钮android:id="@+id/hotseat_left",在launchHotSeat方法中(index等于0)执行以下代码打开相应的Activity。
if (index >= 0 && index < mHotseats.length && mHotseats[index] != null) { Intent intent = mHotseats[index]; startActivitySafely( mHotseats[index], "hotseat" ); }
mHotseats的内容通过loadHotseats方法加载R.array.hotseats。
在Lanucher/res/values/arrays.xml中可以找到打开拨号盘的Intent的具体URL
- 2、在DialerPhoneActivity类中重写onCreate方法
setContentView(R.layout.dialer_key);//加载该界面的布局,各控件如下:
- ListView android:id="@+id/contact_list"用于电话本记录与通话记录的显示,
- ImageButton android:id="@+id/hide_button"用于隐藏键盘,
- ImageButton android:id="@+id/delete_button"用于删除输入的电话号码,
- EditText android:id="@+id/dialer_digits"用于电话号码的输入框,
- layout="@layout/dialer_dialpad"用于各个数字按键的布局,
- layout="@layout/dialer_dialbutton"包含SIM1/SIM2/voice拨号,
- layout="@layout/emergency_button"用于紧急拨号按钮。
initViews();//对该界面各个控件进行初始化,并加入侦听事件
updateContactAndCalllogList();// update contact & calllog list.
registerObserver();//registerObserver to ContactDB changed, 当电话本数据库数据改变时会改变mIsContactChanged的值。该变量用于从其它界面回到该界面时,如果电话本数据库中的数据有改变的话重新加载记录。
- 3、方法updateContactAndCalllogList()
该方法打开了TestThread类的线程,该线程读取通话记录与电话本中的记录,mCustomArrayList中把记录add进来,然后发出REDRAW消息[mHandler.sendEmptyMessage(REDRAW)],再在handleMessage方法中通过以下代码更新至ListView对象。
if (null != mAdapter) { mAdapter.mList.clear(); mAdapter.mList.addAll(mCustomArrayList); mAdapter.notifyDataSetChanged(); } else { mAdapter = new ContactAdapter(mCustomArrayList); mContactList.setAdapter(mAdapter); }
afterTextChanged(mDigits.getText())调用mAdapter.filter根据输入进行过滤。调用ContactAdapter类的binSearch方法对电话号码与姓名进行匹配。
- 4、当键盘有按键时
通过调用onClick方法调用keyPressed方法,执行mDigits的onKeyDown方法。当编辑框中的字串改变后,frameworks层在SpannableStringBuilder类中sendTextHasChanged方法中调用每个TextWatcher的afterTextChanged方法,DialerPhoneActivity类的afterTextChanged根据输入过滤,mAdapter.mList对象重新加载过滤后的结果。再调用notifyDataSetChanged方法通知所附的观察员,基础数据已经改变,任何反映的数据集应该刷新自己。
- 5、当点击界面中搜索结果列表中的某一项时,执行onItemClick方法,mDigits对象的数据设置为选择的项的电话号码,并隐藏拨号盘。
- 6、当点击拨号按钮时执行dialButtonPressed方法,先得到mDigits对象的电话号码,通过以下代码打开呼出电话界面。
intent.setData(Uri.fromParts("tel", number, null)); intent.putExtra(DIALER_SIM,true); intent.putExtra(Phone.PHONE_ID, phoneId); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent);
注:如以上分析有误,欢迎指正。