以前看过好几次的东西又忘记了.或者写下来就会记住了吧...那就写下来~~~
SystemUI中虚拟按键的实现(Home, Back, Recently)
以Home键为例:
在layout中,定义Home键为一个KeyButtonView
从布局上看,每个虚拟按键是KeyButtonView。那么这个class是怎么构造的呢。如下。
publicKeyButtonView(Context context, AttributeSet attrs, int defStyle) {
super(context,attrs);
TypedArraya = context.obtainStyledAttributes(attrs, R.styleable.KeyButtonView,
defStyle,0);
mCode =a.getInteger(R.styleable.KeyButtonView_keyCode, 0);
mSupportsLongpress =a.getBoolean(R.styleable.KeyButtonView_keyRepeat, true);
。。。。。。
setClickable(true);
mTouchSlop= ViewConfiguration.get(context).getScaledTouchSlop();
}
构造函数里头获取了一些关键的属性。
接着继续看这个类怎么用这些属性
public boolean onTouchEvent(MotionEvent ev) {
finalint action = ev.getAction();
intx, y;
switch(action) {
caseMotionEvent.ACTION_DOWN:
//Log.d("KeyButtonView","press");
mDownTime= SystemClock.uptimeMillis();
setPressed(true);
if(mCode != 0) {
sendEvent(KeyEvent.ACTION_DOWN,0, mDownTime);
}else {
//Provide the same haptic feedback that the system offers for virtual keys.
performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
}
if(mSupportsLongpress) {
removeCallbacks(mCheckLongPress);
postDelayed(mCheckLongPress,ViewConfiguration.getLongPressTimeout());
}
break;
caseMotionEvent.ACTION_MOVE:
x= (int)ev.getX();
y= (int)ev.getY();
setPressed(x>= -mTouchSlop
&&x < getWidth() + mTouchSlop
&&y >= -mTouchSlop
&&y < getHeight() + mTouchSlop);
break;
caseMotionEvent.ACTION_CANCEL:
setPressed(false);
if(mCode != 0) {
sendEvent(KeyEvent.ACTION_UP,KeyEvent.FLAG_CANCELED);
}
if(mSupportsLongpress) {
removeCallbacks(mCheckLongPress);
}
break;
caseMotionEvent.ACTION_UP:
finalboolean doIt = isPressed();
setPressed(false);
if(mCode != 0) {
if(doIt) {
sendEvent(KeyEvent.ACTION_UP,0);
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
playSoundEffect(SoundEffectConstants.CLICK);
}else {
sendEvent(KeyEvent.ACTION_UP,KeyEvent.FLAG_CANCELED);
}
}else {
//no key code, just a regular ImageView
if(doIt) {
performClick();
}
}
if(mSupportsLongpress) {
removeCallbacks(mCheckLongPress);
}
break;
}
returntrue;
}
在这里的onTouch中,KeyButtonView处理了触摸事件,同时并派发了消息。
void sendEvent(int action, int flags) {
sendEvent(action,flags, SystemClock.uptimeMillis());
}
void sendEvent(int action, int flags, long when) {
finalint repeatCount = (flags & KeyEvent.FLAG_LONG_PRESS) != 0 ? 1 : 0;
finalKeyEvent ev = new KeyEvent(mDownTime, when, action, mCode, repeatCount,
0,KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
flags| KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY,
InputDevice.SOURCE_KEYBOARD);
InputManager.getInstance().injectInputEvent(ev,
InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
}
onTouch处理后,直接将按键上报。
剩下的R.id.home这个id用来做什么呢。单纯是为了实现触摸效果。