Android控件TextView的实现原理分析
作者:网络转载 发布时间:[ 2013/5/16 10:28:29 ] 推荐标签:
PhoneWindow类的成员函数getCallback是从父类Window继承下来的,它返回的是一个Window.Callback接口。每一个Activity组件都会实现一个Window.Callback接口,并且将这个Window.Callback接口设置到与它所关联的一个PhoneWindow对象的内部去,这样当该PhoneWindow对象接收到键盘事件的时候,可以该键盘事件分发给与它所关联的Activity组件处理。
DecorView类的成员变量mFeatureId用来描述当前正在处理的DecorView对象的特征,当它的值小于0的时候,表示当前正在处理的一个DecorView对象是用来描述一个Activity组件窗口的顶层视图的。
因此,当当前正在处理的DecorView对象描述的是一个Activity组件窗口的顶层视图,并且这个Activity组件实现有一个Window.Callback接口时,DecorView类的成员函数dispatchKeyEvent会调用该Window.Callback接口的成员函数dispatchKeyEvent来通知对应的Activity组件,它接收到一个键盘事件了。否则的话,参数event所描述的键盘事件会被分发给当前正在处理的DecorView对象的父对象来处理,这是通过调用DecorView类的父类View的成员函数dispatchKeyEvent来实现的。
我们假设当前正在处理的DecorView对象描述的是一个Activity组件窗口的顶层视图,并且这个Activity组件实现有一个Window.Callback接口,那么参数event所描述的键盘事件接下来会分给该Activity组件处理。如果该Activity组件在处理完成这个键盘事件之后,希望该键盘事件还能继续分发下去给其它对象处理,那么它所实现的Window.Callback接口的成员函数dispatchKeyEvent的返回值handled会等于false,这时候DecorView类的成员函数dispatchKeyEvent会将该键盘事件分发给与当前正在处理的DecorView对象所关联的一个PhoneWindow对象的成员函数onKeyDown或者onKeyUp来处理,取决于变量isDown的值是true还是false,即当前发生的键盘事件是与按键按下有关,还是与按键松开有关。
PhoneWindow类的成员函数onKeyDown和onKeyUp主要是有来监控一些特殊按键事件,例如电话键和音量键,以便可以执行一些对应的逻辑。例如,当按下电话键时,打开拨号程序;又如,当按下音量键时,调节音量的大小。
接下来,我们继续分析Activity类所实现的Window.Callback接口的成员函数dispatchKeyEvent的实现,以便可以了解键盘事件在Activity组件窗口的分发过程。
Step 7. Activity.dispatchKeyEvent
[java] view plaincopyprint?
public class Activity extends ContextThemeWrapper
implements LayoutInflater.Factory,
Window.Callback, KeyEvent.Callback,
OnCreateContextMenuListener, ComponentCallbacks {
......
public boolean dispatchKeyEvent(KeyEvent event) {
......
Window win = getWindow();
if (win.superDispatchKeyEvent(event)) {
return true;
}
View decor = mDecor;
if (decor == null) decor = win.getDecorView();
return event.dispatch(this, decor != null
? decor.getKeyDispatcherState() : null, this);
}
......
}
public class Activity extends ContextThemeWrapper
implements LayoutInflater.Factory,
Window.Callback, KeyEvent.Callback,
OnCreateContextMenuListener, ComponentCallbacks {
......
public boolean dispatchKeyEvent(KeyEvent event) {
......
Window win = getWindow();
if (win.superDispatchKeyEvent(event)) {
return true;
}
View decor = mDecor;
if (decor == null) decor = win.getDecorView();
return event.dispatch(this, decor != null
? decor.getKeyDispatcherState() : null, this);
}
......
}
这个函数定义在文件frameworks/base/core/java/android/app/Activity.java中。
Activity类的成员函数getWindow返回的是与当前正处理的Activity组件所关联的一个PhoneWindow对象,Activity类的成员函数dispatchKeyEvent获得了这个PhoneWindow对象之后,会调用它的成员函数superDispatchKeyEvent,以便可以将参数event所描述的键盘事件分发给它处理。
这个PhoneWindow对象在处理完成参数event所描述的键盘事件之后,如果希望该键盘事件能继续往下分发,那么Activity类的成员函数dispatchKeyEvent会将该键盘事件分发给当前正在处理的Activity组件处理,这是通过调用参数event所描述的一个KeyEvent对象的成员函数dispatch来实现的。
注意,在调用event所描述的一个KeyEvent对象的成员函数dispatch的时候,第一个参数指定为当前正在处理的Activity组件所实现的一个KeyEvent.Callback接口。参数event所指向的一个KeyEvent对象的成员函数dispatch的执行的过程中,会相应地调用这个KeyEvent.Callback接口的成员函数onKeyDown、onKeyUp或者onKeyMultiple来处理它所描述的键盘事件,实际上是调用Activity类的成员函数onKeyDown、onKeyUp或者onKeyMultiple来处理参数event所描述的键盘事件。因此,我们在自定义一个Activity组件时,如果需要处理分发给该Activity组件的键盘事件,那么需要重写父类Activity的成员函数onKeyDown、onKeyUp或者onKeyMultiple。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11