这几天在做Android 关于keyevent方面的代码的开发,现在记录一下,以备不时之需。
要求
将原来通过Touch触发的SwitchButton的切换事件的代码,移植到不支持触摸的andorid系统上。所以需要进行从TouchEvent变成KeyEvent。为了尽可能的少改动原来的代码,所以通过在原有的UI框架内加一个自定义Layout 的方法来添加焦点事件。
焦点移动流程:
1.在想要获得焦点的控件上添加属性focusable=“true”,并设置好上一个焦点和下一个焦点,nextFocusUp和nextFocusDown,属性值为控件的Id
<FocusFrameLayout
android:id="@+id/focus_apr_setting_layout"
app:enter_response="@+id/apr_setting_switch"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/strokecolor_focus"
android:focusable="true"
android:nextFocusUp="@+id/focus_recovery_log_enable_layout"
android:nextFocusDown="@+id/focus_upload_crash_info_layout">
2.在Activity中实例化一个焦点控件,并吧页面的第一个焦点给它
focusAprSettinLayout.requestFocus();
3.在通过cmd键入
adb shell input keyevent 20 //下一个
adb shell input keyevent 19 //上一个
4.在android stidio中创建的项目,会有已经设置好的获得焦点时和失去焦点时的样式。或者你也可以去自定义。
先创建一个xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" >
<shape>
<stroke
android:width="1dp"
android:color="@color/detail_item_color">
</stroke>
<corners
android:radius="1dp">
</corners>
<padding
android:bottom="2dp"
android:top="2dp"
android:left="2dp"
android:right="2dp"
>
</padding>
</shape>
</item>
</selector>
在item中的android:state_focused是系统自带的属性,如果后面是true,意为当获得焦点的时候。然后在shape中添加样式,stroke为边框,就是当该控件获得焦点时边框宽度变为1dp,颜色为某种颜色,其他属性也可以自己去添加。
最后在控件中把背景属性设置为这个xml
Enter流程:
1.cmd键入指令adb shell input keyevent 66(为enter命令)
2.当前焦点所在的自定义FocusFrameLayout控件中的dispatchkeyevent()接收到该命令,但是需要enter的控件包含在FocusFrameLayout中,如何来获取某一个控件中的在控件名呢?所以需要在FocusFrameLayout中添加一个自定义属性用来传递内部的控件名。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="FocusFrameLayout">
<attr name="enter_response" format="reference">
</attr>
</declare-styleable>
</resources>
然后在FocusFrameLayout的属性里添加
app:enter_response="@+id/apr_setting_switch"
接下来,在FocusFrameLayout中的构造函数中来获取
public FocusFrameLayout (Context context, AttrbuteSet attr) {
TypeArray ta = context.ObtinStyleableAttribute(attr, R.styleable.focusframelayout);
int mResponseId = ta.getResouseId(R.styleable.focusframelayout.enter_response, 0);
}
3.然后在自定义的FocusFrameLayout中重写dispatchkeyevent()方法,在其中进行判断并执行相应命令
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if(event.getKeyCode() == KeyEvent.KEYCODE_ENTER && event.getAction() != KeyEvent.ACTION_UP) {
mReaponseld.performclick();
return true;
}
return super.dispatchKeyEvent(event);
}
2.Click指令在Activity中监听并作出反应
@Override
public void onClick(View v){
}