Detect backspace in TextWatcher [duplicate] - android

This question already has answers here:
Android EditText delete(backspace) key event
(17 answers)
Closed 8 years ago.
I am using TextWatcher and I am unable to detect Backspace key in TextWatcher.afterTextChange event. I also want to clear textView on some condition in textWatcher event.
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
// I want to detect backspace key here
}

To detect a backspace in TextWatcher, you can check the variable count that is passed into the onTextChange function (count will be 0 if a backspace was entered), like this:
#Override
public void onTextChanged(CharSequence cs, int start, int before, int count) {
if (react) {
if (count == 0) {
//a backspace was entered
}
//clear edittext
if(/*condition*/) {
react = false;
setText("");
react = true;
}
}
}
The react boolean is needed for the setText() function otherwise it becomes recursive. Hope this helps!

A KeyListener can fulfil both of your conditions.
mEditText.setOnKeyListener(new OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_DEL){
//on backspace
}
return false
}
});
Similarly inside the onKey(), you can put multiple check statements to check for the condition, when you would want to clear the textView.
EDIT : As #RankoR was kind enough to point out, please bear in mind that onKeyListener() works only for the hardware keyboards and not the soft keyboards.

Related

setText in afterTextChanged in TextWatcher makes holding backspace not working

I'm using addTextChangedListener(myTextWatcher) to my editText for some currency format.
There is setText() in afterTextChanged in my TextWatcher.
public void afterTextChanged(Editable s) {
et.removeTextChangedListener(this);
(snipped)
et.setText(someText);
(snipped)
et.addTextChangedListener(this);
}
The problem is that even though holding backspace I can delete only one character. I found that setText in the afterTextChanged makes holding backspace not working.
I don't know the exact mechanism but it seems setText push up backspace.
In addition it seems this doesn't happen in Android 7.0 but happens android 8.0 and 9.0.
Thank you in advance!
Use this to know when the backspace is pressed:
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) {
editText.setText(editText.getText().tostring()); // gets the current text and sets it again
}
return false;
}
});
You said it works only once. By doing this if you press it it gives you another chance by setting text again and then you can press backspace only once again.

Android: soft keyboard Backspace on EditText not working

This is what happens:
Activity A and B have an EditText and they both have IME_SEARCH. The input is done only via soft keyboard on a SAMSUNG tablet.
On Activity A I can use the EditText without problems. The thing is that on Activity B I can't erase text with backspace after I hit 'space' or whenever I use a word from the suggestions. It behaves like there wasn't text there anymore. If I type new characters, I can erase them up to the space.
Important points:
The View hierarchy that contains the EditTexts are identical
The code that configures the IME_SEARCH processing (via setOnEditorActionListener) is identical
The TextWatcher of both are also identical
In the Manifest, both activities are configures with
android:configChanges="keyboardHidden|keyboard|orientation"
android:windowSoftInputMode="stateAlwaysHidden|adjustUnspecified"
I set a breakpoint on the method beforeTextChanged of both TextWatcher. I inserted a 'space' and hit 'backspace'. On the Edittext of activity A, the method is triggered but on activity B's it is not triggered. I can't see the reason for this to happen since the properties of both Edittext are configured identically.
I also tried removing the IME option but the behavior kept the same.
Does anyone know what could be happening?
EDIT 1:
searchTxt.addTextChangedListener(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) {
}
#Override
public void afterTextChanged(Editable s) {
if (s.length() == 0) {
btnClear.setVisibility(View.GONE);
} else{
btnClear.setVisibility(View.VISIBLE);
}
}
});
searchTxt.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
buildGrid();
return true;
}
return false;
}
});
EDIT 2:
The layout hierarchy is as following.
<LinearLayout
... >
<include layout="#layout/title_bar" />
<RelativeLayout
...>
<EditText
...>
The problem was that, for some reason, the Activity B was overriding dispatchKeyEvent() and always returning true. Removing it solved the problem.
I have similar problems that you are facing and I somehow managed to stumble on the solution. Apparently, I had setOnKeyListener to 'return true'. After I changed it to 'return false', the phone keyboard works perfect with backspace functioning properly once again on edittext. Hope this helps:
.setOnKeyListener(new View.OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
...
return false;
}
});

Android - catch backspace (delete) button on custom EditText

I want to catch the backspace/delete button event in soft keyboard on EditText custom.
How can I do it ?
I tried these solutions but they do not work for me :
Android custom EditText and back button override
EditText OnKeyDown
Get back key event on EditText
Android EditText delete(backspace) key event
Thanks for your help !
EDIT :
I found a fix for that isssue with the function DispatchKeyEvent :
#Override public boolean dispatchKeyEvent(#NonNull KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN
&& event.getKeyCode() == KeyEvent.KEYCODE_DEL) {
// ...
}
return super.dispatchKeyEvent(event);
}
I found a fix for that isssue with the function DispatchKeyEvent :
#Override public boolean dispatchKeyEvent(#NonNull KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN
&& event.getKeyCode() == KeyEvent.KEYCODE_DEL) {
// ...
}
return super.dispatchKeyEvent(event);
}
Catching Key Events from soft input methods in Android is unreliable. Here is an excerpt from the JavaDoc for the KeyEvent class:
As soft input methods can use multiple and inventive ways of inputting
text, there is no guarantee that any key press on a soft keyboard will
generate a key event: this is left to the IME's discretion, and in
fact sending such events is discouraged. You should never rely on
receiving KeyEvents for any key on a soft input method. In particular,
the default software keyboard will never send any key event to any
application targetting Jelly Bean or later, and will only send events
for some presses of the delete and return keys to applications
targetting Ice Cream Sandwich or earlier.
One workaround could involve using TextWatcher. Whenever a delete occurs in an EditText, the character count drops.
myEditText.addTextChangedListener(this);
//...
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (count == 0) {
//text was deleted.
}
}
Edit: This is untested, so may not be completely reliable. In addition, it's worth pointing out that count may also read 0 if a long section of text is selected and then replaced. I created a library once that was designed to add Undo/Redo functionality to EditText, but can also identify the difference between text being replaced and deleted, so this may be of use to you if you require more accuracy.
Please, take a look at a solution I provided in another similar topic: Android - cannot capture backspace/delete press in soft. keyboard. You need to build your custom EditText class and override onCreateInputConnection method in it. It will give you access to deleteSurroundingText event which is firing when you click backspace. I've tested it in some devices and hope it will work in others also. Try it and give a feedback.
Here you go..
editText.addTextChangedListener(new TextWatcher() {
private int before;
private int after;
private int prevLength;
private boolean isBackPressed;
ArrayList<Integer> arrayList;
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
prevLength = charSequence.length();
}
#Override
public void onTextChanged(CharSequence charSequence, int start, int end, int count) {
}
#Override
public void afterTextChanged(Editable editable) {
isBackPressed = prevLength > editable.length();
if(isBackPressed){
Toast.makeText(getApplicationContext(),"Back",Toast.LENGTH_LONG).show();
}
}
});

Space Key event behaviour on Numeric Input field?

I created two EditText with "android:inputType="number" property.
here I am using hardware Keyboard, so when I perform Space Key event on textField, focus control directly shift from editText view to some other random view of screen. In normal text field type it took it as an another character, that's fine.
Any one have idea how can use Space key event to retain focus on same field.
Using editText.setInputType(InputType.TYPE_CLASS_NUMBER) may probably solve your problem.
Change/Add your EditText Property with android:imeOptions="actionNext" like as follows
<EditText
android:id="#+id/edit_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:imeOptions="actionNext"
android:inputType="text" />
Or with android:imeOptions="actionNone" for default behavior of EditText
<EditText
android:id="#+id/edit_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:imeOptions="actionNone"
android:inputType="text" />
So it looks like your problem doesn't have to do with the 'input' type of your EditText, but rather the key press events coming from the keyboard....
So 'hopefully' this should fix your problem for you (by 'skipping over' the 'next' event from the 'space' button being pressed.)
// do for both EditText(s)
editText1.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
log.d("main","KeyPress:"+ actionID);
if (event != null ) { log.d("main","KeyPress:" + event.getKeyCode() ); }
if ( actionId == EditorInfo.IME_ACTION_NEXT) {
// do 'nothing' or 'add a space' if you want that
return true;
}
return false;
}
});
This is likely what is happening (hard to tell without your XML)
So I found something that should help you figure out the pattern + possibly lead to solving it... from https://stackoverflow.com/a/17990096
if there is a android:nextFocus.... setting in your XML (or equivalent in code) and/or the physical keyboard 'space' is also signalling IME_ACTION_NEXT (or another IME action similar to it)
If the EditorInfo.IME_ACTION_NEXT isn't the IME action that is causing your problems, then you can try this... to determine WHAT is.
from: https://stackoverflow.com/a/4171427
if you have PHYSICAL keyboard you can use to detect keyDown events and handle them appropriately,
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
log.d("main","KeyPress:" + keyCode);
if (event != null ) { log.d("main","KeyPress:" + event.getKeyCode() ); }
// if you want to 'handle' the keyPess here, best to use switch like below
// switch (keyCode) {
// case KeyEvent.KEYCODE_A:
// {
// //your Action code
// return true;
// }
/// }
return super.onKeyDown(keyCode, event);
}
BUT... if you have software keyboard You need to use addTextChangedListener/TextWatcher Because the physical key press is 'eaten' by the EditText (from what I saw in another post, but seems to be correct from my testing.)
mMyEditText.addTextChangedListener(new TextWatcher()
{
public void afterTextChanged(Editable s)
{
}
public void beforeTextChanged(CharSequence s, int start, int count, int after)
{
/*This method is called to notify you that, within s, the count characters beginning at start are about to be replaced by new text with length after. It is an error to attempt to make changes to s from this callback.*/
}
public void onTextChanged(CharSequence s, int start, int before, int count)
{
}
);
You can override what the EditText does when a 'space' is entered.
This seems pretty easy when in 'software keyboard', but physical keyboard seems to be a bit more difficult.
https://developer.android.com/reference/android/widget/TextView.OnEditorActionListener.html
Similar to this question (but 'space' instead of 'enter') Android - Handle "Enter" in an EditText
This could help you determine the 'pattern' of the focus being changed. if it is random or not (most likely -not- random, but possibly 'interesting' to look into)
http://developer.android.com/reference/android/view/View.OnFocusChangeListener.html
// try this to see
View.OnFocusChangeListener changeListener = new View.OnFocusChangeListener()
{
#Override
public void onFocusChange(View v, boolean hasFocus) {
log.d("YourClassName", "FocusChanged" + hasFocus)
}
};
EditText1.setOnFocusChangeListener(changeListener);
EditText2.setOnFocusChangeListener(changeListener);
Button.setOnFocusChangeListener(changeListener);
// ... etc... (add to views to see if there is pattern)

OnTextChang for edittext in android?

I have 8 edit texts each allow only one character.when user enter something it automatically moves to next edit text. It's work fine by using onTextchanged.But i need to move backward also like when user enter back button it automatically moves to previous edit text and when enter something it move again next edit text. How i can do it.Please can any one help.
Any help would be highly appreciated.
editText_Pin1.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence s, int start,int before, int count) {
if(editText_Pin1.getText().toString().length()==1) { //size as per your requirement {
editText_Pin2.requestFocus();
}
}
public void beforeTextChanged(CharSequence s, int start,int count, int after) {
}
#Override
public void afterTextChanged(Editable arg0) {
}
});
Try something like this...
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK)) {
if(editText_Pin2.getText().toString().length()==1){//Here you will check the last editField which has lenght == 1
editText_Pin1.requestFocus();
return false;//This will make sure your activity doesn't gets finished
}
}
return super.onKeyDown(keyCode, event);
}
Hope this helps..
you can do it by oveeriding the onBackPressed method
#Override
public void onBackPressed() {
//check here which edittext has current focus,change the focus to previous edittext
//you can use edittext array also.And also check if it is the first edittext then do nothing
return;
}
You have several options:
Activity.onBackPressed()
Activity.onKeyDown() or Activity.onKeyUp()
View.setOnKeyListener() on each of your EditTexts
View.onKeyPreIme()
I'd probably go with #1 or #3

Categories

Resources