Android EditText删除(退格)键事件

如何检测editText的删除(backspace)事件? 我试过使用TextWatcher,但是当editText为空时,当我按下删除键时,什么都不会发生。 即使没有文字,我也想检测删除键是否为editText。

Solutions Collecting From Web of "Android EditText删除(退格)键事件"

注意: onKeyListener不适用于软键盘。

您可以为您的editText设置OnKeyListener ,以便您可以检测到任何按键
编辑:我们正在检查KeyEvent.KEYCODE_BACK backspace ,但真的是KeyEvent.KEYCODE_DEL (真的那个名字是混乱!

 editText.setOnKeyListener(new 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 } return false; } }); 

自从你问了一段时间以来,我只是有同样的问题。 正如Estel已经提到的,关键听众的问题是他们只能使用硬件键盘。 要使用IME(软键盘)执行此操作,该解决scheme稍微复杂一些。

我们想要重写的单一方法是EditTextInputConnection类中的sendKeyEvent 。 在IME中发生按键事件时调用此方法。 但是为了覆盖这个,我们需要实现一个自定义的EditText ,它覆盖了onCreateInputConnection方法,将默认的InputConnection对象封装在代理类中! :|

听起来很复杂,但这是我可以devise的最简单的例子:

 public class ZanyEditText extends EditText { private Random r = new Random(); public ZanyEditText(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public ZanyEditText(Context context, AttributeSet attrs) { super(context, attrs); } public ZanyEditText(Context context) { super(context); } public void setRandomBackgroundColor() { setBackgroundColor(Color.rgb(r.nextInt(256), r.nextInt(256), r .nextInt(256))); } @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) { ZanyEditText.this.setRandomBackgroundColor(); // Un-comment if you wish to cancel the backspace: // return false; } return super.sendKeyEvent(event); } } } 

调用setRandomBackgroundColor是我的特殊退格动作发生的地方。 在这种情况下,改变EditText的背景颜色。

如果你是从XML膨胀这个记得使用完整的包名称作为标记:

 <cc.buttfu.test.ZanyEditText android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/somefield" ></cc.buttfu.test.ZanyEditText> 

这只是Idris的答案的一个补充,在override中也join了deleteSurroundingText。 我在这里发现更多的信息: Android:退格在WebView / BaseInputConnection

 package com.elavon.virtualmerchantmobile.utils; import java.util.Random; import android.content.Context; import android.graphics.Color; 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; public class ZanyEditText extends EditText { private Random r = new Random(); public ZanyEditText(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public ZanyEditText(Context context, AttributeSet attrs) { super(context, attrs); } public ZanyEditText(Context context) { super(context); } public void setRandomBackgroundColor() { setBackgroundColor(Color.rgb(r.nextInt(256), r.nextInt(256), r .nextInt(256))); } @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) { ZanyEditText.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); } } } 

我发了2天find一个解决scheme,我想出了一个工作:)(在软键上)

 public TextWatcher textWatcher = new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { if (count == 0) { //Put your code here. //Runs when delete/backspace pressed on soft key (tested on htc m8) //You can use EditText.getText().length() to make if statements here } } @Override public void afterTextChanged(Editable s) { } } 

将textwatcher添加到您的EditText后:

 yourEditText.addTextChangedListener(textWatcher); 

我希望它可以在另一个Android设备(三星,LG等)。

这是我的简单解决scheme,适用于所有的API:

 private int mPreviousLength; private boolean mBackSpace; // ... @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { mPreviousLength = s.length(); } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void afterTextChanged(Editable s) { mBackSpace = mPreviousLength > s.length(); if (mBackSpace) { // do your stuff ... } } 

使用TextWatcher创buildEditText的示例

 EditText someEdit=new EditText(this); //create TextWatcher for our EditText TextWatcher1 TW1 = new TextWatcher1(someEdit); //apply our TextWatcher to EditText someEdit.addTextChangedListener(TW1); 

自定义TextWatcher

 public class TextWatcher1 implements TextWatcher { public EditText editText; //constructor public TextWatcher1(EditText et){ super(); editText = et; //Code for monitoring keystrokes editText.setOnKeyListener(new View.OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { if(keyCode == KeyEvent.KEYCODE_DEL){ editText.setText(""); } return false; } }); } //Some manipulation with text public void afterTextChanged(Editable s) { if(editText.getText().length() == 12){ editText.setText(editText.getText().delete(editText.getText().length() - 1, editText.getText().length())); editText.setSelection(editText.getText().toString().length()); } if (editText.getText().length()==2||editText.getText().length()==5||editText.getText().length()==8){ editText.setText(editText.getText()+"/"); editText.setSelection(editText.getText().toString().length()); } } public void beforeTextChanged(CharSequence s, int start, int count, int after){ } public void onTextChanged(CharSequence s, int start, int before, int count) { } } 

在Stackoverflow中有一个类似的问题。 您需要重写EditText才能访问包含deleteSurroundingText方法的InputConnection对象。 它将帮助您检测删除(退格)事件。 请看看我提供的解决schemeAndroid – 无法捕获退格/删除按软。 键盘

这似乎是为我工作:

 public void onTextChanged(CharSequence s, int start, int before, int count) { if (before - count == 1) { onBackSpace(); } else if (s.subSequence(start, start + count).toString().equals("\n")) { onNewLine(); } } 

我也面临同样的问题在对话..因为我使用setOnKeyListener ..但我设置默认返回true。 改变后像下面的代码,它为我工作得很好..

  mDialog.setOnKeyListener(new Dialog.OnKeyListener() { @Override public boolean onKey(DialogInterface arg0, int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { mDialog.dismiss(); return true; } return false;//this line is important } }); 

基于@Jiff ZanyEditText这里是WiseEditTextsetSoftKeyListener(OnKeyListener)

 package com.locopixel.seagame.ui.custom; import java.util.Random; import android.content.Context; import android.graphics.Color; import android.support.v7.widget.AppCompatEditText; import android.util.AttributeSet; import android.view.KeyEvent; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputConnectionWrapper; public class WiseEditText extends AppCompatEditText { private Random r = new Random(); private OnKeyListener keyListener; public WiseEditText(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public WiseEditText(Context context, AttributeSet attrs) { super(context, attrs); } public WiseEditText(Context context) { super(context); } @Override public InputConnection onCreateInputConnection(EditorInfo outAttrs) { return new MyInputConnection(super.onCreateInputConnection(outAttrs), true); } private class MyInputConnection extends InputConnectionWrapper { public MyInputConnection(InputConnection target, boolean mutable) { super(target, mutable); } @Override public boolean sendKeyEvent(KeyEvent event) { if (keyListener != null) { keyListener.onKey(WiseEditText.this,event.getKeyCode(),event); } 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); } } public void setSoftKeyListener(OnKeyListener listener){ keyListener = listener; } } 

我的问题是,我有自定义Textwatcher ,所以我不想将OnKeyListener添加到EditText以及我不想创build自定义EditText 。 我想检测是否在我的afterTextChanged方法按下退格键,所以我不应该触发我的事件。

这是我解决这个问题的方法。 希望这会对某人有所帮助。

 public class CustomTextWatcher extends AfterTextChangedTextWatcher { private boolean backspacePressed; @Override public void afterTextChanged(Editable s) { if (!backspacePressed) { triggerYourEvent(); } } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { super.onTextChanged(s, start, before, count); backspacePressed = count == 0; //if count == 0, backspace is pressed } } 

我已经在版本4.2,4.4,6.0上testing了@ Jeff的解决scheme。 在4.2和6.0上,它运行良好。 但在4.4,它不起作用。

我发现一个简单的方法来解决这个问题。 关键是在开始时在EditText的内容中插入一个不可见的字符,并且不要让用户在这个字符之前移动光标。 我的方法是插入一个零宽度ImageSpan的空白字符。 这是我的代码。

  @Override public void afterTextChanged(Editable s) { String ss = s.toString(); if (!ss.startsWith(" ")) { int selection = holder.editText.getSelectionEnd(); s.insert(0, " "); ss = s.toString(); holder.editText.setSelection(selection + 1); } if (ss.startsWith(" ")) { ImageSpan[] spans = s.getSpans(0, 1, ImageSpan.class); if (spans == null || spans.length == 0) { s.setSpan(new ImageSpan(getResources().getDrawable(R.drawable.zero_wdith_drawable)), 0 , 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } } } 

我们需要定制一个EditText,它有一个SelectionChangeListener

 public class EditTextSelectable extends android.support.v7.widget.AppCompatEditText { public interface OnSelectChangeListener { void onSelectChange(int start, int end); } private OnSelectChangeListener mListener; public void setListener(OnSelectChangeListener listener) { mListener = listener; } ...constructors... @Override protected void onSelectionChanged(int selStart, int selEnd) { if (mListener != null) { mListener.onSelectChange(selStart, selEnd); } super.onSelectionChanged(selStart, selEnd); } 

}

最后一步

 holder.editText.setListener(new EditTextSelectable.OnSelectChangeListener() { @Override public void onSelectChange(int start, int end) { if (start == 0 && holder.editText.getText().length() != 0) { holder.editText.setSelection(1, Math.max(1, end)); } } }); 

现在,我们完成了〜当EditText没有实际的内容时,我们可以检测退格键事件,用户对我们的技巧一无所知。

这个问题可能会老,但使用TextWatcher的答案是非常简单的。

 int lastSize=0; @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { //2. compare the old length of the text with the new one //3. if the length is shorter, then backspace was clicked if (lastSize > charSequence.length()) { //4. Backspace was clicked //5. perform action } //1. get the current length of of the text lastSize = charSequence.length(); } 

您可以在活动上设置关键侦听器,并且在callback方法中,您可以检测到用户点击了哪个键。 下面的代码供您参考。 希望能帮助到你。

 //after user hits keys, this method would be called. public boolean onKeyUp(int keyCode, KeyEvent event) { if (editText.isFocused()) { switch (keyCode) { case KeyEvent.KEYCODE_DEL: //delete key Log.i("INFO", "delete key hit"); //you should see this log in ddms after you hit delete key break; } } return super.onKeyUp(keyCode, event); }