Android 检测软键盘中的删除按钮

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12083540/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 09:41:17  来源:igfitidea点击:

Detect delete button in soft keyboard

androidandroid-edittextandroid-softkeyboard

提问by michael_ferl

I have two EditText (each only only accepts one character) and I want to handle both fields like I had only one.

我有两个 EditText(每个只接受一个字符),我想处理这两个字段,就像我只有一个一样。

I'm using a TextWatcher to set the focus in the second one when the user writes a character in the first one, but I don't know how to do the opposite.

当用户在第一个字符中写入字符时,我正在使用 TextWatcher 在第二个字符中设置焦点,但我不知道如何做相反的事情。

If the user press the delete button in the second EditText (being this EditText empty) I want to move the focus to the first EditText and delete the character there.

如果用户按下第二个 EditText 中的删除按钮(此 EditText 为空),我想将焦点移动到第一个 EditText 并删除那里的字符。

The problem is that TextWatcher doesn't work when the user tries to delete an empty field (because in fact nothing is changing). And onKeyDown event only works with hard keyboards so I don't have any idea of how to deal with this problem...

问题是当用户尝试删除空字段时 TextWatcher 不起作用(因为实际上没有任何变化)。而且 onKeyDown 事件只适用于硬键盘,所以我不知道如何处理这个问题......

Thanks!

谢谢!

采纳答案by sandrstar

Possible duplicate of Android EditText delete(backspace) key event

Android EditText delete(backspace) 键事件的可能重复

just checked the code from that question (which actually come from the provided question and answered by Labeeb P) with the test project with just two edits on layout and it seems to work just fine - I'm able to receive delete even if edit is empty.

刚刚检查了该问题中的代码(实际上来自提供的问题并由 Labeeb P 回答)与测试项目中的布局仅进行了两次编辑,它似乎工作得很好 - 即使编辑是,我也可以收到删除空的。

    final EditText edit1 = (EditText) findViewById(R.id.editText1);

    edit1.setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            // You can identify which key pressed buy checking keyCode value
            // with KeyEvent.KEYCODE_
            if (keyCode == KeyEvent.KEYCODE_DEL) {
                // this is for backspace
                Log.e("IME_TEST", "DEL KEY");
            }
            return false;
        }
    });

Seems android documentation of EditText should be made more clear or at least any guide for EditText - Soft Keyboard interaction provided, because there many typical ones whose should be worked out by nearly every developer.

似乎 EditText 的 android 文档应该更清楚,或者至少提供 EditText - Soft Keyboard 交互的任何指南,因为几乎每个开发人员都应该制定出许多典型的文档。

UPDATE:Seems this way doesn't work on latest (at least after 4.1) Android versions. This answerseems to work on versions after 4.1.

更新:似乎这种方式不适用于最新的(至少在 4.1 之后)Android 版本。这个答案似乎适用于 4.1 之后的版本。

回答by AlexOlsen

A simpler solution to this that I stumbled upon is using an InputFilter. InputFilter's filter()method appears to report all soft keyboard events - even those where the EditText's value isn't changing.

我偶然发现的一个更简单的解决方案是使用InputFilter。InputFilter 的filter()方法似乎报告所有软键盘事件——即使是那些 EditText 的值没有改变的事件。

So to address your specific situation, construct an input filter and set accordingly:

因此,为了解决您的具体情况,请构建一个输入过滤器并进行相应设置:

private InputFilter filter = (charSequence, start, end, dest, dStart, dEnd) -> {

    if (end == 0 || dStart < dEnd) {
        // backspace was pressed! handle accordingly
    }

    return charSequence;
};

...

myEditText.setFilters(new InputFilter[] { filter });

Backspace events can be evaluated using end, dStart, and dEnd. dStartwill always be less than dEndif a character was deleted. If the EditTextis empty, you can still evaluate backspace presses by checking if end== 0.

Backspace键事件可以使用进行评估enddStartdEnddStart将始终小于dEnd删除字符时的值。如果EditText为空,您仍然可以通过检查 if end== 0来评估退格键。

Note that bulk deletes will also be caught in this ifstatement, so you may want to do some extra checking withing filter(). Also note that if you're using your computer keyboard to type into EditTexts in emulators, you can get unexpected results. Best to click software buttons for testing.

请注意,此if语句中也会捕获批量删除,因此您可能需要对filter(). 另请注意,如果您使用计算机键盘在模拟器中输入 EditTexts,您可能会得到意想不到的结果。最好点击软件按钮进行测试。

回答by Irshu

Use the Extension provided at, https://github.com/ciasaboark/Android-Shell/blob/master/src/com/example/com/programmingthetux/tutorial/ZanyEditText.java

使用https://github.com/ciasaboark/Android-Shell/blob/master/src/com/example/com/programmingthetux/tutorial/ZanyEditText.java提供的扩展

import java.util.Random;

import android.content.Context;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputConnectionWrapper;
import android.widget.EditText;
/**
 * Created by mkallingal on 4/25/2016.
 */
public class CustomEditText extends EditText {

    private Random r = new Random();

    public CustomEditText(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

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

    public CustomEditText(Context context) {
        super(context);
    }

    public void setRandomBackgroundColor() {

    }

    @Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
        return new ZanyInputConnection(super.onCreateInputConnection(outAttrs),
                true);
    }

    private class ZanyInputConnection extends InputConnectionWrapper {

        public ZanyInputConnection(InputConnection target, boolean mutable) {
            super(target, mutable);
        }

        @Override
        public boolean sendKeyEvent(KeyEvent event) {
            if (event.getAction() == KeyEvent.ACTION_DOWN
                    && event.getKeyCode() == KeyEvent.KEYCODE_DEL) {
                CustomEditText.this.setRandomBackgroundColor();
                // Un-comment if you wish to cancel the backspace:
                // return false;
            }
            return super.sendKeyEvent(event);
        }


        @Override
        public boolean deleteSurroundingText(int beforeLength, int afterLength) {
            // magic: in latest Android, deleteSurroundingText(1, 0) will be called for backspace
            if (beforeLength == 1 && afterLength == 0) {
                // backspace
                return sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL))
                        && sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL));
            }

            return super.deleteSurroundingText(beforeLength, afterLength);
        }

    }
}

Now you can use it in your Activity like so:

现在您可以像这样在您的活动中使用它:

final CustomEditText editText = new CustomEditText(cxt);

editText.setOnKeyListener(new View.OnKeyListener() {
                    @Override
                    public boolean onKey(View v, int keyCode, KeyEvent event) {
                        if (keyCode == KeyEvent.KEYCODE_DEL) {
                            String _text= editText.getText().toString();
                            if(StringUtils.isBlank(_text))
                                 //editText is now empty
                            }
                        }
                        return false;
                    }
                });

回答by Ayaz Alifov

I achieved it by overriding EditTextin order to get access to InputConnectionobject which contains deleteSurroundingTextmethod. It helps to detect deletion (backspace) event. Please, take a look at a solution I provided there: Android - cannot capture backspace/delete press in soft. keyboard

我通过覆盖EditText以访问InputConnection包含deleteSurroundingText方法的对象来实现它。它有助于检测删除(退格)事件。请看一下我在那里提供的解决方案:Android - 无法捕捉退格/删除软按下。键盘

This solution works properly for both hardKeyboard and softKeyboard.

此解决方案适用于 hardKeyboard 和 softKeyboard。