Android EditText OnKeyListener 不起作用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24425838/
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
EditText OnKeyListener not working
提问by Ammar
I know this/similar questionhas been asked before but the solution given is not working for me so I'm asking again. I tried the solution given in that answer but still my OnKeyListener is never being invoked on some devices, especially the ones with stock OS. I need to detect pressing of del key of soft keyboard when when there is no character in editText. Here is my code;
我知道之前已经问过这个/类似的问题,但给出的解决方案对我不起作用,所以我再问一次。我尝试了该答案中给出的解决方案,但仍然从未在某些设备上调用过我的 OnKeyListener,尤其是那些具有库存操作系统的设备。当editText中没有字符时,我需要检测软键盘的del键的按下。这是我的代码;
EditText et = (EditText) findViewById(R.id.et);
et.setOnKeyListener(new EditText.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
Log.d("OnKeyListener", keyCode + " character(code) to send");
return false;
}
});
回答by Ammar
Finally solved myself by implementing this feature through TextWatcher
. The major hurdle was that, I needed to detect backspace press even when there is no character in EditText
or at least the end user perceives that there is no character there. The fist thing couldn't be achieved however I did the later one. Following is the detailed solution.
最后通过TextWatcher
. 主要的障碍是,即使没有字符EditText
或至少最终用户认为那里没有字符,我也需要检测退格键。第一件事无法实现,但我做了后一件。下面是详细的解决方法。
First of all, I always retained a space ' ' character in my editText
.
首先,我总是在我的editText
.
editText.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
if(cs.toString().length() == 0)
editText.setText(" ");
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { }
@Override
public void afterTextChanged(Editable arg0) { }
});
Then I customized EditText
to notify me for every cursor position change. This purpose is achieved by overriding onSelectionChanged
method of EditText
. My customized EditText
looks like this.
然后我定制EditText
了每次光标位置变化时通知我。这个目的是通过覆盖 的onSelectionChanged
方法来实现的EditText
。我的定制EditText
看起来像这样。
public class SelectionEnabledEditText extends EditText {
public SelectionEnabledEditText(Context context) {
super(context);
}
public SelectionEnabledEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SelectionEnabledEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onSelectionChanged(int selStart, int selEnd) {
super.onSelectionChanged(selStart, selEnd);
if(onSelectionChangeListener != null)
onSelectionChangeListener.onSelectionChanged(selStart, selEnd);
}
public static interface OnSelectionChangeListener{
public void onSelectionChanged(int selStart, int selEnd);
}
private OnSelectionChangeListener onSelectionChangeListener;
public void setOnSelectionChangeListener(OnSelectionChangeListener onSelectionChangeListener) {
this.onSelectionChangeListener = onSelectionChangeListener;
}
}
Finally, in my activity, I'm listening for cursor position changed event and resetting my cursor position in editText
if it's there at the necessary space charatcer start i.e. at 0th index, like this;
最后,在我的活动中,我正在监听光标位置更改事件并重置我的光标位置,editText
如果它在必要的空格字符开始处,即在第 0 个索引处,就像这样;
editText.setOnSelectionChangeListener(new SelectionEnabledEditText.OnSelectionChangeListener() {
@Override
public void onSelectionChanged(int selStart, int selEnd) {
if (selEnd == 0) {
if (editText.getText().toString().length() == 0)
editText.setText(" ");
editText.setSelection(1);
}
}
});
Hope this would be helpful in similar situations. Suggestions are welcomed for improvements/optimizations.
希望这在类似情况下会有所帮助。欢迎提出改进/优化建议。
回答by Ameer
The documentation states that the key events will only be propagated for the hardware key strokes, not software.
该文档指出,按键事件只会针对硬件按键而不是软件进行传播。
http://developer.android.com/reference/android/view/View.OnKeyListener.html
http://developer.android.com/reference/android/view/View.OnKeyListener.html
The device manufacturers are actually being discouraged to propagate soft keyboard events through key listeners, although it is completely up to the manufacturer to honour that or to actually treat the soft and hard keyboards with equal terms.
实际上不鼓励设备制造商通过键侦听器传播软键盘事件,尽管完全取决于制造商是否尊重这一点或实际上以同等条件对待软键盘和硬键盘。
Starting from Android 4.2.2, Android system itself will not support key stoke events for the soft keyboards at all, so even the manufacturers will not be able to choose their way.
从 Android 4.2.2 开始,Android 系统本身将完全不支持软键盘的按键事件,因此即使是制造商也无法选择他们的方式。
So the only foolproof option here is to implement your own IME (soft keyboard), and handle the keystrokes yourself.
因此,这里唯一的万无一失的选择是实现您自己的 IME(软键盘),并自己处理击键。
TextWatcher can be used mostly to replace the key listeners, however editText.setText(...); will also trigger the TextWatcher events, so if one is interested in typed keys only then probably TextWatcher is not a solution either.
TextWatcher 主要用于替换关键侦听器,但是 editText.setText(...); 也会触发 TextWatcher 事件,所以如果一个人只对键入的键感兴趣,那么 TextWatcher 也不是一个解决方案。
Please be cautious when using TextWatcher with AutocomleteTextView or EditText. Do not modify text in the AutocompleteTextView / EditText's content from within TextWatcher events, cause otherwise you'll most probably end up in an infinite event/listening loop.
将 TextWatcher 与 AutocomleteTextView 或 EditText 一起使用时请小心。不要在 TextWatcher 事件中修改 AutocompleteTextView / EditText 内容中的文本,否则很可能会导致无限事件/侦听循环。
回答by Guillaume Barré
Based on the documentationof the OnKeyListener
it seems that the callback is invoked only for hardware keyboards.
根据文档,OnKeyListener
似乎只为硬件键盘调用回调。
Interface definition for a callback to be invoked when a hardware key event is dispatched to this view. The callback will be invoked before the key event is given to the view. This is only useful for hardware keyboards; a software input method has no obligation to trigger this listener.
当硬件按键事件被分派到这个视图时要调用的回调的接口定义。回调将在键事件提供给视图之前被调用。这仅对硬件键盘有用;软件输入法没有义务触发这个监听器。
回答by rehman_00001
There's an attribute for EditText: android:imeOptions
EditText 有一个属性: android:imeOptions
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/main_editor"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:imeOptions="actionGo"
/>
I noticed that for values: actionGo
, actionNone
, normal
, actionSearch
onKeyListener got called.
我注意到对于 values: actionGo
, actionNone
, normal
, actionSearch
onKeyListener 被调用了。
P.S. It even worked without specifying that attribute.!
PS它甚至在没有指定该属性的情况下也能工作。!
回答by Lockon
Try something like this :
尝试这样的事情:
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_DEL) {
//Log key
Log.d("OnKeyListener", keyCode + " character(code) to send");
}
return false;
}