对Android 软键盘向下的监听

因为业务需要,有时候我们好监听软键盘向下的动作,当我们按下向下的按钮时,可以进行监听,从而执行相应的动作。

于是我们写下下面的代码

 @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK){
            Log.i(TAG, "onKeyDown");
        }
        return super.onKeyDown(keyCode, event);
    }

我们按下向下的按钮,滴,没反应。再按一次,滴,握草,直接退出了,这个时候才有 log 打印出来。这个 log 是退出当前 Activity, 而不是软键盘向下的。

如果没有想到好的解决方案,就问 google , 于是我们得到了解决方法,就是对 Edittext.onKeyPreIme() 方法重写

/**
 *  拦截键盘向下的 EditTextView
 */
public class TextEditTextView extends EditText {
    public TextEditTextView(Context context) {
        super(context);
    }

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

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

    @Override
    public boolean onKeyPreIme(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == 1) {
            Log.i("main_activity", "键盘向下 ");
            super.onKeyPreIme(keyCode, event);
            return false;
        }
        return super.onKeyPreIme(keyCode, event);
    }
}

在布局中

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    android:id="@+id/activity_main"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/white">

    <com.yxhuang.myapplication.TextEditTextView
        android:id="@+id/edt_text"
        android:layout_width="match_parent"
        android:hint="测试"
        android:layout_marginTop="30dp"
        android:textColorHint="@android:color/black"
        android:layout_height="wrap_content"/>

</RelativeLayout>

点击向下后,可以看到 log

这是键盘向下的监听,我们得到了,然后可以执行相应的动作。

作为一个程序员,我们不仅要知道怎样做,还应该知道为什么会这样。这个问题就涉及到 Android 输入系统,详情见上一篇博文 Android 输入系统

为什么 重写 Activity.onKeyDown() 方法为什么没有用?

根据 Android 输入系统 一文,我们知道事件的流水线处理顺序

Ime 是键盘输入法, ViewPreImeStage 是在输入法之前,ImeStage 是输入法处理,ViewPostImeStage 才是最终传递到 Activity.onKeyDown() 的。

ViewPreImeStage 中可以将键盘向下的事件传递到 View, 而到了 ViewPostImeStage 则没有,那应该是有东西消耗了这个事件。当我们按下向下的按钮,键盘会收起来,显然是键盘消耗了这个事件。

我们看看 ImeStage 的源码

 /**
     * Delivers input events to the ime.
     * Does not support pointer events.
     */
    final class ImeInputStage extends AsyncInputStage
            implements InputMethodManager.FinishedInputEventCallback {
        public ImeInputStage(InputStage next, String traceCounter) {
            super(next, traceCounter);
        }

        @Override
        protected int onProcess(QueuedInputEvent q) {
            if (mLastWasImTarget) {
                // 获取 InputMethodManager 实例
                InputMethodManager imm = InputMethodManager.peekInstance();
                if (imm != null) {
                    final InputEvent event = q.mEvent;
                    // dispatchInputEvent 方法处理了事件
                    int result = imm.dispatchInputEvent(event, q, this, mHandler);
                    if (result == InputMethodManager.DISPATCH_HANDLED) {
                        return FINISH_HANDLED;
                    } else if (result == InputMethodManager.DISPATCH_NOT_HANDLED) {
                        return FINISH_NOT_HANDLED;
                    } else {
                        return DEFER; // callback will be invoked later
                    }
                }
            }
            return FORWARD;
        }

        @Override
        public void onFinishedInputEvent(Object token, boolean handled) {
            QueuedInputEvent q = (QueuedInputEvent)token;
            if (handled) {
                finish(q, true);
                return;
            }
            forward(q);
        }
    }

我们看到如果 InputMethodeManager.dispatchInputEvent(…) 方法返回的结果是

InputMethodManager.DISPATCH_HANDLED 则结束事件的传递。事件就传递不到 ViewPostImeStage, 从而也就传递不到 Activity.onKeyDown() 中了。

到这来我们终于知道了为什么重写 Activity.onKeyDown() 方法没用了,想要监听键盘向下的事件,需要重写 Edittext.onKeyPreime() 方法,在这个方法里进行监听了。

时间: 2024-10-16 07:47:23

对Android 软键盘向下的监听的相关文章

Android项目:输入法软键盘显示/隐藏的监听和控制,InputMethodManager用法研究

在项目开发中,用到编辑框的地方经常涉及到要监听或者控制软键盘的显示/隐藏状态.本以为这是很容易解决的一个小问题,没想到当初碰到这个问题才明白还得花点小心思才能整好.现将针对软键盘的显示/隐藏状态的监听/监控方法做一些总结,以备后用. 一.点击空白处隐藏软键盘 这是具有编辑框焦点的页面对输入法软键盘状态监听的一般需求和解决方法. 首先获得InputMethodManager:        InputMethodManager manager = (InputMethodManager) getS

android设置软键盘搜索键以及监听搜索键点击时发生两次事件的问题解决

如图所示,有时候为了布局美观,在搜索时没有搜索按钮,而是调用软件盘上的按钮.调用的实现只需要在XML在输入框中加入android:imeOptions="actionSearch",调用软键盘时,回车键就会显示搜索二字. 然后调用 OnEditorActionListener,不是OnKeyListener searchText.setOnEditorActionListener(new OnEditorActionListener() { @Override public boole

android 软键盘在全屏下的布局计算问题

在非全屏模式下,将activity的windowSoftInputMode的属性设置为:adjustResize.同时在View的onSizeChanged(int w, int h, int oldw, int oldh)里可以得到变化后的尺寸,然后根据前后变化的结果来计算屏幕需要移动的距离. 但是在全屏模式下,即使将activity的windowSoftInputMode的属性设置为:adjustResize.在键盘显示时它未将Activity的Screen向上推动,所以你Activity的

关于android软键盘enter键的替换与事件监听

android软键盘事件监听enter键 软件盘的界面替换只有一个属性android:imeOptions,这个属性的可以取的值有 normal,actionUnspecified,actionNone,actionGo,actionSearch,actionSend,actionNext,actionDone, 例如当值为actionNext时enter键外观变成一个向下箭头,而值为actionDone时enter键外观则变成了“完成”两个字. 我们也可以重写enter的事件,方法如下 Jav

完美解决android软键盘监听

最近在做应用性能调优,发现在一个包含有输入框的Activity中,当软键盘弹出的时候,如果直接finish掉此Activity,那么在返回到上一个Activity时,界面的渲染会由于软键盘没有及时的收起而出现卡顿的情况. 很不友好. 于是,本着geek的精神,做就做到极致,就尝试着对这一块做优化. 借助网上一些知识的分享,同时结合自己的理解,最终应用到项目中. 直接上代码.. 首先,在manifest文件中声明此Activity的windowSoftInputMode属性, 1 android:

完美解决android软键盘监听1

最近在做应用性能调优,发现在一个包含有输入框的Activity中,当软键盘弹出的时候,如果直接finish掉此Activity,那么在返回到上一个Activity时,界面的渲染会由于软键盘没有及时的收起而出现卡顿的情况. 很不友好. 于是,本着geek的精神,做就做到极致,就尝试着对这一块做优化. 借助网上一些知识的分享,同时结合自己的理解,最终应用到项目中. 直接上代码.. 首先,在manifest文件中声明此Activity的windowSoftInputMode属性,      andro

【转载】android软键盘的一些控制

原文地址:http://blog.csdn.net/wang_shaner/article/details/8467688 "EditText + Button"  形成一个 "输入+按键响应" 的案例在android编程中是最常见不过的了. 但还有一些细节需要注意: 在EditText输入后,点击Button进行请求,软键盘应该自行消失 在EditText输入后,不点击Button进行请求,而是直接点击软键盘上的"回车",那么也应该能够正常响应

android 软键盘回车键捕获

EditText editText2 = (EditText)findViewById(R.id.txtTest2); editText2.setOnEditorActionListener(new OnEditorActionListener() { @Override public boolean onEditorAction(TextView arg0, int arg1, KeyEvent arg2) { if (arg1 == EditorInfo.IME_ACTION_UNSPECI

android软键盘enter键

enter键,回车键,电脑键盘上enter键就有多种响应.android软键盘也不例外 你在EditText上输入以后,想在下一行输入框输入,可能需要去点击下一行输入框,让它获取焦点,也可能要隐藏软键盘,在点击输入框,弹出软键盘. 或者已经到了最后一行输入框,输入完毕以后,要点击登录,注册,或者链接按钮,可能要去隐藏它,感觉操作狠繁琐.用户体验不好,有没有解决办法呢? 其实可以利用软键盘的enter键来解决上面的体验问题. 软键盘,最常用的enter键事件有: 把EditText的Ime Opt