06.输入系统:第10课第18节_输入系统_InputStage_实验_截取输入事件

前面的小节,我们讲解了InputStage的理论知识,该小节我们编写源代码,对理论知识进行验证。之前的APP_0008_ViewHierarcky上进行修改,更改文件名为APP_0009_Inputstage。

使用AS打开该工程,首先给应用程序添加一个文本对话框,然后修改这个对话框的文本处理函数。进入工程的layout下的activity_main.xml文件,可以通过手动添加(plan text)也可以添加以下内容:

<EditText
    android:id="@+id/editText2"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:ems="10"
    android:inputType="textPersonName"
    android:text="Name" />
添加完成之后,我们先确定一下我们实验的步骤以及目的。
1.在输入法之前添加自己的处理函数
		重写onKeyPreIme方法
2.在输入法之后添加自己的处理函数
		a.在显示字符之前添加处理函数
		b.在显示字符之后添加处理函数
		c.给某个控件注册监听者:setOnKeyListener,或者重写控件的onKeyDown,onKeyUp方法。
3.添加善后处理函数(如果所有的View控件无法处理按键,由Activity来处理)。
		重写Activity的onKeyDown,onKeyUp方法

我们先来看看第一步,给某个控件重写onKeyPreIme方法,要给这个控件重写方法,我们必须从这个控件派生出子类。文本框的类型为EditText,选中MainActivity右键点击New进而选中java Class如下:
在这里插入图片描述
然后取名为MyEditText,同时再修改content_main.xml,把EditText修改为com.example.administrator.app_0001_leddemp.MyEditText,完成之后回到MyEditText.java文件,让其继承于EditText,并且使用快捷键CTRL+O实现其所有构造函数,使用父类的即可:

ublic class MyEditText extends EditText {
    public MyEditText(Context context) {
        super(context);
    }

    public MyEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyEditText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public MyEditText(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }
}

还是使用CTRL+O,选中onKeyPreIme方法,然后进行重写,我们先做简单一点,随便打印一些信息即可:

	private String TAG = "LedDemo";
	/*获取按键是松开还是按下*/
    public String getKeyStatus(KeyEvent event){
        if(event.getAction() == KeyEvent.ACTION_DOWN)
            return "down";
        else
            return "up";
    }

    @Override
    public boolean onKeyPreIme(int keyCode, KeyEvent event) {
        Log.d(TAG, "onKeyPreIme: "+ keyCode + getKeyStatus(event));
        return super.onKeyPreIme(keyCode, event);
    }

编写完成之后,我们运行程序,由于我们重写的是onKeyPreIme按键方法,如果使用开发板测试,需要接上接盘才可以,当我们按下按键和松开的时候,可以看到不一样的打印信息。

我们把onKeyPreIme的return super.onKeyPreIme(keyCode, event)修改成 return true;:

        return true;
       // return super.onKeyPreIme(keyCode, event);

当我们按下键盘的时候,发现没有任何反应了,因为此时已经被截取了, return true代表InputStage已经被完成了,就不会把他传给下一个Stage。

下面我们给该控件添加一个监视器,在这之前先修改content_main.xml文件,给MyEditText添加一个id:

	android:id="@+id/MYEDITTEXT1"

再修改MainActivity.java代码中的onCreate方法,添加如下代码:

       myEditText.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
                Log.d(TAG,"OnKeyListener.onkey" +keyCode+""getKeyStatus(keyEvent))

                return false;
            }
        });

其中getKeyStatus的实现与之前的一样:

    /*获取按键是松开还是按下*/
    public String getKeyStatus(KeyEvent event){
        if(event.getAction() == KeyEvent.ACTION_DOWN)
            return "down";
        else
            return "up";
    }

编译运行之后,我们可以看到类似OnKeyListener.onkey67 up的打印信息,代表监视按键成功,在onKey中返回的是return false,代表没有被截取,该事件会继续传递给下个Stage,交给其他函数处理。如果我们把其改为return true,编译运行,我们键盘输入,但是开发板的编辑框没有反应。

下面我们重写控件的setOnKeyListener,与onKeyDown函数()。以及Activity的setOnKeyListener,与onKeyDown函数:
MyEditText.java添加如下:

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        Log.d(TAG, "Activity onKeyDown: "+ keyCode + getKeyStatus(event));
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        Log.d(TAG, "Activity onKeyUp: "+ keyCode + getKeyStatus(event));
        return super.onKeyUp(keyCode, event);
    }

MainActivity.java

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        Log.d(TAG, "Activity onKeyDown: "+ keyCode + getKeyStatus(event));
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        Log.d(TAG, "Activity onKeyUp: "+ keyCode + getKeyStatus(event));
        return super.onKeyUp(keyCode, event);
    }

编译运行程序,可以看到如下打印

D/LedDemo: onKeyPreIme: 54down
D/LedDemo: OnKeyListener.onkey54 down
D/LedDemo: MyEditText onKeyDown: 54down
D/LedDemo: onKeyPreIme: 54up
D/LedDemo: OnKeyListener.onkey54 up
D/LedDemo: MyEditText onKeyUp: 54up
D/LedDemo: Activity onKeyUp: 54up

可以看出,在松开的时候MyEditText 没有做处理,最后由Activity 处理。

下面我们组个实验,让我们输入的是a键,然后显示的是b键。字符的显示是在onKeyDown中实现的,那么我们修改MyEditText的方法就可以了:

    public KeyEvent createAnotherKeyEvent(KeyEvent event) {
        return new KeyEvent(event.getDownTime(),event.getEventTime(),event.getAction(), event.getKeyCode()+1,event.getRepeatCount(),event.getMetaState(),event.getDeviceId(),event.getScanCode());
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        Log.d(TAG, "MyEditText onKeyDown: "+ keyCode + getKeyStatus(event));
        // return super.onKeyDown(keyCode, event);
        return super.onKeyDown(keyCode+1, createAnotherKeyEvent(event));
    }

编译运行之后,我们输入a,得到的是b。其他的按键都是加1.

猜你喜欢

转载自blog.csdn.net/weixin_43013761/article/details/88577555