前文有朋友回复说想深入了解一下拨号盘源码的实现,也许是上文中,我对此说的不够细致,现将拨号盘点击事件及处理,拨号键的点击等。
对于拨号盘的界面显示,在此就不在浪费大家的时间,不清楚的朋友可以点击下面的连接(拨号盘界面的显示)。下面主要描述一下点击拨号盘中某个按钮后,是怎么将对应的数字显示在输入框中和点击控制键(拨号,删除,搜索)所触发的事件。
1.拨号盘中数字键
在DialpadFragment.java中,通过onCreateView方法,加载出了拨号界面,在该方法中有一句这样的令人费解的代码
if (oneButton != null) {
}
private void setupKeypad(View fragmentView) {
View view = fragmentView.findViewById(R.id.one);
view.setOnClickListener(this);
view.setOnLongClickListener(this);
….
}
废话不多说,看代码!
1.1数字键盘的点击事件
view.setOnClickListener(this);
为其设置点击事件监听器。此时该监听器为当前对象this,看样子该Fragment实现了view的onClickListener接口,是不是呢?我们看代码
DialpadFragment extends Fragment implements View.OnClickListener
好,既然如此,肯定要覆盖onClick(View view) 方法,我们继续跟进
onClick方法的片段如下
@Override
public void onClick(View view) {
}//switch结束
}//onClick结束
这个方法主要是根据不同的按键发出不同的声音,最总调到本地方法,和显示关系不大,就不做详细描述,有需要的朋友自己看一下,java代码比较简单。
keyPressed(KeyEvent.KEYCODE_1);
我们来看这句的代码
}
第一句mHaptic.vibrate();
我们先来看看mHaptic 到底是个什么东西吧
// Vibration (haptic feedback) for dialer key presses.
private HapticFeedback mHaptic = new HapticFeedback();
该HapticFeedback是一个Android定义的类,该类的vibrate()方法的大体上就是是手机震动一下。
继续跟进
KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
mDigits.onKeyDown(keyCode, event);
通过传递过来的键盘码,构造键盘点击事件,然后将该事件交给EditText的子类对象mDigits进行处理。处理后就会将keyCode所代表的字符显示在输入框内。
final int length = mDigits.length();
}
后面几句,就是设置光标的可见与否。onCilck事件我们已经分析完毕,所有按键的点击均会触发该事件,回过头来,我们继续跟进setupKeypad方法。
1.2数字键盘的长按事件
view.setOnLongClickListener(this);
相关代码片段如下:
public boolean onLongClick(View view) {
dialogFragment.show(getFragmentManager(), "voicemail_not_ready");
}//switch 语句结束
return false;
}//onLongClick方法结束
公共代码分析
final Editable digits = mDigits.getText();
获得输入框EditText的输入数据,获得view的id号码,用于switch语句的分支确认。
通过上面的基本操作,我们找到了长按1事件的主体,R.id.one分支
映入眼帘的第一句
看代码
private boolean isDigitsEmpty() {
}
简单的说就是判断该输入框内是否有输入
当没有输入时首先执行isVoicemailAvailable()方法,我们看源码
private boolean isVoicemailAvailable() {
通过源码可以看出,该方法实际上是判断了VoiceMailNumber是否为null,按照源码中的意思,这个条件永远成立,有兴趣的朋友可以去看一下源码。
当没有输入且可以拨打voicemail时执行如下
我们查看源码
public void callVoicemail() {
}
继续跟进
private Intent newVoicemailIntent() {
}
不用多说,是跳转到另一个动作,其实voicemail类似于快捷拨号,在settings中可以设置成自己需要拨打的特殊号码,这样当长按1时,就可以自动拨打出去。
在不符合上面条件的前提下
当没有输入而Activity不等于null时执行dialogFragment 的弹出操作,在此不做过多的说明。
通过对1按键的描述,我想大家已经可以按该过程有所了解。
2.拨号盘中删除键
我们从onCreateView方法中,找到
mDelete = mAdditionalButtonsRow.findViewById(R.id.deleteButton);
mDelete.setOnClickListener(this);
mDelete.setOnLongClickListener(this);
接下来我们分删除键的点击事件和长按事件两部分描述。
2.1 删除键的点击描述
通过上文mDelete.setOnClickListener(this),我们知道,单击事件需要找onClick方法,直接定位到指定位置。
。。。。。。
KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL);
2.2 删除键长按描述
废话不说,直接看定位代码
………..
}
}
Digits.clear()方法,直接清空输入框内的数字
mDelete.setPressed(false); 设置删除键的按下状态
3.拨号盘中拨号键
同理,在onClick方法中找到拨号键
mHaptic.vibrate(); 震动一下
继续查看dialButtonPressed()方法
在该方法中,通过输入域内是否为null建立了两个分支结构,在两个分支中均做了比较多的分支,最终页面实现跳转或对话框的弹出等,比较简单,需要的朋友请自己查看dialButtonPressed()方法的源码。
4.拨号盘中搜索键
搜索按键的处理与其它按键的处理类似,但是又有些不同,在后文将详细的分析一下,感兴趣的朋友自己走一下onClick流程。
希望我的分析,对朋友你有所帮助。