当软键盘显示时,如何处理Android返回键事件?

11

当软键盘显示时,我想捕获“返回”键事件。

我正在使用SDK版本8,并且只有在软键盘隐藏时才能成功地捕获返回键事件,如下所示:

@Override
public void onBackPressed() {
    // do something
    super.onBackPressed();
}

问题在于当软键盘出现时,系统没有调用此方法。我尝试过记录onKeyDown/Up()方法以及上述方法,以弄清楚在这种情况下发生了什么,但是没有成功。请参见以下内容:

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
    //DEBUGGING
    Log.d(TAG + "KeyUP", String.valueOf(event));
}

记录返回了音量和菜单键的操作,但只有在软键盘和菜单隐藏时才记录了后退键。

是否有任何“后退键”方面的专家可以解释这种现象?

非常感谢任何帮助。

3个回答

14

以下是捕获返回键事件的方法: 1. 扩展editText视图以覆盖onKeyPreIme方法。

package com.test.test;
import android.content.Context;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.widget.EditText;

/**
 * Created by sumit.saurabh on 11/10/16.
 */
public class ChatEditText extends EditText
{
    /* Must use this constructor in order for the layout files to instantiate the class properly */
    public ChatEditText(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    private KeyImeChange keyImeChangeListener;

    public void setKeyImeChangeListener(KeyImeChange listener)
    {
        keyImeChangeListener = listener;
    }

    public interface KeyImeChange
    {
        public void onKeyIme(int keyCode, KeyEvent event);
    }

    @Override
    public boolean onKeyPreIme(int keyCode, KeyEvent event)
    {
        if (keyImeChangeListener != null)
        {
            keyImeChangeListener.onKeyIme(keyCode, event);
        }
        return false;
    }
}
  • 在xml中使用的聊天输入框(ChatEditText)

  •     <com.test.test.ChatEditText
            android:id = "@+id/messageEditText"
            android:layout_width = "match_parent"
            android:layout_height = "wrap_content"
            android:layout_gravity = "bottom"
            android:layout_marginLeft = "12dp"
            android:layout_marginRight = "30dp"
            android:background = "@null"
            android:hint = "Type your message"
            android:inputType = "textMultiLine"
            android:singleLine = "false"
            android:textColorHint = "#c4c0bd"
            android:textSize = "18sp"/>
    
    然后将一个监听器(setKeyImeChangeListener)附加到编辑文本框上:
    private ChatEditText messageEditText;
    messageEditText =
       (ChatEditText) findViewById(R.id.messageEditText);
    
    messageEditText.setKeyImeChangeListener(new ChatEditText.KeyImeChange(){
        @Override
        public void onKeyIme(int keyCode, KeyEvent event)
        {
            if (KeyEvent.KEYCODE_BACK == event.getKeyCode())
            {
                // do something
            }
        }});
    

    1
    回调函数被多次调用,有没有更好的方法来避免这种情况?@Sumit - Dart

    8
    在进一步研究了该网站和Android API后,我发现:
    KeyEvent.KEYCODE_BACK
    

    如果输入法编辑器(IME)与输入法连接且当前显示(换句话说,软键盘未隐藏),则会捕获并吞噬此事件。这意味着在系统调用Activity类的onKeyDown()或onKeyUp()方法之前,该事件已被消耗。

    为了解决这个问题,创建一个您的IME小部件(TextView或其子类,如EditText)的子类,并实现onKeyPreIme()

    Stack用户i2097i在此处发布了一个实现onKeyPreIme()的好方法here。 只需确保在您的onKeyPreIme()覆盖中返回FALSE,如果您希望保留Android的默认行为(即关闭键盘)。


    0
    通常情况下,返回按钮会隐藏键盘(原生行为),因此在这方面做任何事情都不是一个好主意。

    我同意你的观点,Joan。但在我的情况下,我只希望隐藏EditText小部件(如果它是可见的),并同时隐藏键盘的默认行为。 - dan

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接