setOntouchListener和setOnKeyListener

3 篇文章 0 订阅
2 篇文章 0 订阅

       学过android一段时间的朋友们都知道,android系统界面事件的传递和处理的原则:

       如果界面控件设置了监听器,则事件将先传递给事件监听器,如果没有设置监听器,则会直接传递给界面控件的其他事件处理方法;而是否能够继续传递事件给其他方法是由事件监听器的返回值决定的:

       ①事件监听器处理方法返回值为false(函数生成时的默认返回值),则表示此事件没有被监听器完成处理过程,或者还需要其他的事件处理方法来捕获并处理此事件,这样此事件就会被传递给其他能够处理此事件的处理方法;

       ②事件监听器处理方法返回值为true,则表示此事件已经被监听器处理完成,不需要其他事件处理方法来处理,这样此事件就不会继续往下进行传递。 

       初学android,在学习过程中无意中发现在针对EditText编辑时,针对setOnTouchListener和setOnKeyListener进行一系列调试和研究,得出以下结论(此说明只针对EditText):

       setOnTouchListener:

       setOnTouchListener 的onTouch方法优先级比onTouchEvent高,会先触发;若onTouch方法返回false,会接着触发onTouchEvent,反之则不会被调用;

       setOnTouchListener中的onTouch方法返回值是true(事件被处理完成)时,则onTouchEvent(Activity的方法)方法将不会执行,例如不会打开系统软键盘;若返回值是false(事件未被完全处理,需要往下传递,需要别的处理方法来处理此事件)时,onTouchEvent方法才会被执行,例如会打开系统软键盘,在AVD模拟器上,经测试发现,如果你触摸长时间没有松开,当你松开触摸时,也不会进行onTouchEvent方法的响应,这里是因为点击触摸和长按触摸会产生两种不同的事件,而长按触摸键会调用ContextMenu类的相关实现方法,具体的可以在长按触摸操作中重写这个类的相关方法以实现想要的长按触摸效果,例如画圆等等。

       setOnKeyListener:

       setOnKeyListener在事件传递这方面和setOnTouchListener是类似的。但是setOnKeyListener是针对键盘的监听者,例如手机键盘、外设键盘,下面我就从手机键盘和外设键盘对setOnKeyLisetener针对监听器返回值的不同进行不同的响应处理进行分析:

       ①如果setOnKeyListener的OnKey()返回值是false,在前面的介绍中说过,它需要把此事件传递下去给其他的事件处理方法处理,所以如果从外设键盘输入字符(包括字母、数字、符号、enter、del、回退等)监听器都能实现对按键事件的监听并处理,然后向下传递,EditText捕获到此事件,把它显示在EditText控件内,下面附上效果图:

从上面可以看到,输入a、b、1都能被监听器监听到并进行响应处理,然后被EditText捕获到进行显示处理。

如果从系统软键盘输入字符(包括字母,数字,符号等),发现监听器除了对数字进行响应并处理,对其余的字符都没有进行响应处理,就传给了EditText控件并显示在控件内,附上效果图:


从上面几幅图可以看到输入1时,监听器监听到并处理,而输入@、f都不能被监听到,然后被EditText捕获进行显示处理。

       从以上两种情况可以看出,在setOnKeyListener监听器中,从外设键盘得到了想要的效果,而在系统软键盘中只能从数字的输入看到效果而无法对其他字符进行响应处理。

       ②如果setOnKeyListener的OnKey()返回值是true,在前面的介绍中说过,在监听器中就已经完成处理,不需要继续往下传交给其他事件处理,所以需要的内容不会显示在EditText控件中。

如果从外设键盘中输入字符,监听器监听到了按键并且做出了响应,但是没有往下传,所以在EditText控件中不会显示输入的内容,附上效果图:

从上面三幅图中可以看到,输入q,监听器监听到了q的按下与松开,并作出了反应,从后面两幅图来看,按下1和enter也是一样的效果。

如果从系统软键盘输入字符,发现监听器除了监听到数字的输入并进行处理,而其他的字符都没有监听到并处理,而是由EditText捕获到并且进行显示处理,附上效果图:


从上面可以看到输入1时,监听器监听到1被按下,并且进行响应处理,输入¥、a、enter都没有被监听器监听到,而是被EditText捕获到并且进行显示处理了。

       从上面两种情况可以看到,setOnKeyListener在外设键盘的输入下能监听到所有的字符输入,但是由于onKey()方法返回的是true,所以在监听并处理后就不再往下传,而在系统软键盘中,除了数字输入是与外设键盘一样,其他的字符都没有被监听器监听到而被EditText控件捕获到进行显示处理。

        综上所述:onTouchListener是针对触摸进行响应的,而onKeyListener是针对外设键盘的输入进行监听并响应。由于初学android对很多空间里面的实现机制不了解,所以无法对从系统软键盘输入监听器的监听和响应问题进行合理的解释。以上仅是个人经过调试研究所得结果与大家分享,若有对上面的解释不合理或者错误之处,望大家指正批评。

        转载:android.widget.EditText的OnKeyListener监听器在系统自带的软键盘是不起作用的,如果想监听EditText里面的文本改变事件,可以使用addTextChangedListener监听器。

最后呈上代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context="com.touchorkey.ResponseActivity">

       <EditText
           android:id="@+id/response_et"
           android:layout_width="match_parent"
           android:layout_height="wrap_content" />

       <TextView android:id="@+id/content_tv"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="按键事件信息" >
       </TextView>

</LinearLayout>
package com.touchorkey;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;


public class ResponseActivity extends Activity{

    private EditText editText;
    private TextView textView;
    public static final String TAG="ResponseActivity";
    int count=0;
    int num=0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_response);
        editText=(EditText)findViewById(R.id.response_et);
        textView=(TextView)findViewById(R.id.content_tv);
        editText.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                Log.d(TAG, "onTouch: "+count);
                count++;
                return false;
                /*return true不会响应键盘打开事件,但是有响应触摸事件
                也就是说在响应触摸按下和松开后,事件就被消费而不往下传递了
                return false时,在触摸被松开的时候响应打开键盘事件,
                如果触摸长时间被按下,触摸松开时也不会对其他时间进行相应
                例如,不会打开系统默认键盘。
                */

            }
        });
        editText.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View view, int i, KeyEvent keyEvent) {
                Log.d(TAG, "onKey: "+num);
                num++;
                int metaState = keyEvent.getMetaState();
                int unicodeChar = keyEvent.getUnicodeChar();
                String msg = "";
                msg +="按键动作:" + String.valueOf(keyEvent.getAction())+"\n";
                msg +="按键代码:" + String.valueOf(i)+"\n";
                msg +="按键字符:" + (char)unicodeChar+"\n";
                msg +="UNICODE:" + String.valueOf(unicodeChar)+"\n";
                msg +="重复次数:"+ String.valueOf(keyEvent.getRepeatCount())+"\n";
                msg +="功能键状态:" + String.valueOf(metaState)+"\n";
                msg +="硬件编码:" + String.valueOf(keyEvent.getScanCode())+"\n";
                msg +="按键标志:" + String.valueOf(keyEvent.getFlags())+"\n";
                textView.setText(msg);
                return false;
            }
        });
    }
}






  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值