Android: soft keyboard Backspace on EditText not working - android

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;
}
});

Related

Android ListView with EditText loses focus when the keyboard displays. Keyboards appear randomly

I am an iOS developer, and I have been given task to fix this.
After digging and googling, I have no idea what to do.
We have this screen:
This screen is Activity with custom Fragment, containing ListView fed by ArrayAdapter.
The adapter produces views by getView it seems.
Every row has seven EditText controls.
Problem 1:
When screen is shown first time, and you tap on any EditText, nothing happens.
Why?
When you tap second time, and any subsequent time, focus works, keyboard appears, and you can type.
Problem 2:
This is hard to describe. On some devices, tapping any EditText causes keyboards to switch between some numeric and alphanumeric types, and this goes on and on and then stops.
Why?
After trying various stuff:
getExtractedText on inactive InputConnection warning on android
onClick event is not triggering | Android
Android EditText doesn't show the Keyboard
...
I have no idea what is the problem.
According to one of SO posts, you should not have both onClick and onTouch, yet here they are.
Why?
editText.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
view.requestFocus();
break;
}
return false;
}
});
editText.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
((EditText) v).selectAll();
}
});
editText.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_ENTER) {
if (event.getAction() == KeyEvent.ACTION_UP) {
InputMethodManager imm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
}
return false;
}
});
editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
double amount = Double.parseDouble(((EditText)v).getText().toString());
DecimalFormat df = new DecimalFormat("0.0");
String result = df.format(amount);
((EditText)v).setText(result);
}
}
});
}
I am still digging, commenting out various code, but I am in dark, please help.
Whole code: https://gist.github.com/MartinBergerDX/473c47b008b6b0570466794f221eca31
Update 1:
I have removed all listeners, onTouch, onFocus, and text watchers.
And this is still happening:
Update 2:
It seems this is related to keyboard covering ListView. Not sure why, but when I set less than 10 items in data source, keyboard does not cover content and ping pong effect does not happen.
I am not sure if you have xml for this view or you are generating these edittext programatically if you have xml then for each edit text do android:inputType="number" if you are generating these editext programatically then do this for each edittext.setInputType(InputType.TYPE_NUMBER_FLAG_SIGNED | InputType.TYPE_CLASS_NUMBER); with this only number key willl be shown for user input next just add addTextChangedListener to each editText
editText.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) {
//handle your changes here
}
#Override
public void afterTextChanged(Editable s) {
}
});
Update
Android ListView with EditText loses focus when the keyboard displays The issue is when you have a ListView with input capable fields that displays the soft keyboard on focus, the EditText loses its focus for the first time but the second time it just works fine. The reason it happens is all the views are getting rendered again, so the EditText field object in the item row that used to be focused is now a completely different object. android:descendantFocusability="beforeDescendants" in your ListView and android:windowSoftInputMode="adjustPan" for your activity in the app Manifest
<ListView android:id="#+id/productList" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_alignLeft="#+id/search"
android:layout_below="#+id/search"
android:padding="5dp"
android:descendantFocusability="beforeDescendants"/>
<activity android:name=".myActivity"
android:label="#string/app_name" android:screenOrientation="sensorPortrait" android:windowSoftInputMode="adjustPan"/>
Reference https://www.mysamplecode.com/2013/02/android-edittext-listview-loses-focus.html
maybe this is useful for you:
How can I detect a click in an onTouch listener?
Try deleting onClick and using onTouch only, wish it helps.

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

OnKeyListener problem enabling a button

Thanks in advance for your answers. I am working on a basic tax calculator to help me better understand the fundamentals to the Android SDK. The user enters a subtotal and a tax rate (.08) and they press calculate to calculate the solution. I disable the calculate button until both fields have contents. My problem is that when the user enters numbers for both of the fields, the calculate button is still disabled. I posted the code I currently am running (the OnKeyListener). The edittext fields are registered to the listener.
private OnKeyListener mKeyListener = new OnKeyListener()
{
#Override
public boolean onKey(View v, int keyCode, KeyEvent event)
{
switch(v.getId())
{
case R.id.txtSub:
cmdSubmit.setEnabled(txtTax.getText().length()>0
&& txtSub.getText().length() > 0);
break;
case R.id.txtTax:
cmdSubmit.setEnabled(txtTax.getText().length()>0
&& txtSub.getText().length() > 0);
break;
}
return false;
}
};
If you look at the spec for OnKeyListener you'll notice that it gets invoked BEFORE the KeyEvent is given to the view. Other than that this looks right: I would suspect you aren't binding the listener to the right view. Put a break point in the method and make sure it is getting invoked correctly.
I've personally found the TextWatchers a much nicer way of keeping track of whether an EditText has data or not:
TextWatcher tw = new TextWatcher() {
#Override
public void afterTextChanged(Editable s) {
cmdSubmit.setEnabled(!Utils.isStringBlank(txtTax.getText().toString()) &&
!Utils.isStringBlank(txtSub.getText().toString()));
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
};
txtTax.addTextChangedListener(tw);
txtSub.addTextChangedListener(tw);

Categories

Resources