How to stop focus from moving between EditText fields on ENTER - android

I'm making a shopping cart app that dynamically generates rows as items get added. For each item row, an EditText field is used for the item quantity so that quantities can be modified. Since the quantities need to be integers for calculations, I'm using a parseInt to convert the text grabbed from an altered EditText and trapping out any NFEs in case the input was bad.
When the input is good, everything works fine. When the input is bad, the EditText is set back to its prior value (as desired) but if there is another (dynamically-generated) row below it, the focus shifts to the EditText in that lower row. The desired behavior is for the focus to remain in the EditText that the user wants to change.
Regarding what happens to focus on a successful change -- the virtual keyboard closes on success and nothing keeps focus. In that try/catch block I try to hide the keyboard, but that doesn't help ... it stays open on shifting to the lower field.
Here's an image if it helps to visualize:
before and after hitting ENTER
I've read other posts about using requestFocus() and I've used it here but it doesn't seem to have any effect -- maybe due to all this being generated on the fly? I've also seen posts saying that dynamically generated views don't have any IDs you can grab for being a bit more specific in identifying what should get the focus, but perhaps I'm not understanding it in this context.
So, how do I keep the focus in the field the user wants to edit after handling the NFE and resetting the value of that field?
Here's the specific code that catches that NFE:
try {
quantity = Integer.parseInt(quantityCell.getText().toString());
} catch (NumberFormatException nfe) {
Toast.makeText(getApplicationContext(), "Please enter a valid number",
Toast.LENGTH_LONG).show();
imm.hideSoftInputFromWindow(quantityView.getWindowToken(), 0);
quantityCell.setText("" + savedQuantity);
quantityCell.requestFocus();
return false;
}
... and here is all the code that goes into generating that EditText field on the fly:
// create quantity edittext and add to row
final EditText quantityView = new EditText(this);
quantityView.setLayoutParams(cellParams);
quantityView.setSingleLine();
quantityView.setPadding(5, 5, 5, 5);
quantityView.setText("" + theQuantity);
quantityView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// capture old value of quantity before changing it
EditText et = (EditText)v;
savedQuantity = Integer.parseInt(et.getText().toString());
return false;
}
});
quantityView.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN)
if (keyCode == KeyEvent.KEYCODE_ENTER) {
int quantity;
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
TableRow theRow = (TableRow) v.getParent();
TextView nameCell = (TextView) theRow.getChildAt(0);
String name = nameCell.getText().toString();
EditText quantityCell = (EditText) theRow.getChildAt(1);
try {
quantity = Integer.parseInt(quantityCell.getText().toString());
} catch (NumberFormatException nfe) {
Toast.makeText(getApplicationContext(), "Please enter a valid number",
Toast.LENGTH_LONG).show();
imm.hideSoftInputFromWindow(quantityView.getWindowToken(), 0);
quantityCell.setText("" + savedQuantity);
quantityCell.requestFocus();
return false;
}
TextView unitCell = (TextView) theRow.getChildAt(2);
double unit = Double.parseDouble(unitCell.getText().toString().substring(1));
TextView totalCell = (TextView) theRow.getChildAt(3);
double total = Double.parseDouble(totalCell.getText().toString().substring(1));
totalPrice -= total;
totalQuantity -= quantity;
cartDB.changeQuantity(name, quantity, unit);
removeAllRows();
writeOrderTable();
imm.hideSoftInputFromWindow(quantityView.getWindowToken(), 0);
return true;
}
return false;
}
});
// set length of edittext line
productRow.addView(quantityView);
EDIT:
Looking at the code in that catch clause, I'm guessing that the line to hide the virtual keyboard wouldn't do much if the desired field retained any focus in the first place, so maybe I should remove it. The reason it's there is that I tried doing that (hiding the virtual keyboard) to just remove any focus at all and that approach did not work. The field below still grabbed focus and the keyboard remained open.
ANOTHER EDIT:
This does not happen with a physical keyboard -- at least when using by computer keyboard with a Genymotion virtual device (can't use a built-in AVD, I have an AMD cpu). When the same simulator is set to use a virtual keyboard, the problem appears.
FINAL EDIT:
I altered the try/catch block to this and it works as desired. Changes are in the catch clause:
try {
quantity = Integer.parseInt(quantityCell.getText().toString());
} catch (NumberFormatException nfe) {
Toast.makeText(getApplicationContext(), "Please enter a valid number",
Toast.LENGTH_LONG).show();
quantity = savedQuantity;
}
Some code later in the larger block above winds up handling resetting the field when the user inputs bad data. I'm guessing the cause of what was happening was me trying to restore the old value with that setText() method in the old code.

I saw a possible answer here: http://imax-live.blogspot.hk/2012/12/prevent-enter-key-on-edittext-as-multi.html
The idea is to override the keyborad input so that the user cannot use the normal function of the "enter" key
Btw, you can set android:inputType="number" in xml so that only numbers can be entered into the edit text field
class MyTextView extends EditText
{
...
#Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if (keyCode==KeyEvent.KEYCODE_ENTER)
{
// Just ignore the [Enter] key
return true;
}
// Handle all other keys in the default way
return super.onKeyDown(keyCode, event);
}
}

Related

Android switching focus makes keyboard disappear

I want to switch between two EditText views when KEYCODE_DEL button is pressed.
My code works, it indeed focuses previous EditText, but when it does that, the keyboard vanishes, and cursor is located before the actual text in that EditText.
To make it more vivid, when the focus switches, the EditText looks like this:
|23 where | is the cursor position and keyboard is hidden.
Here is my code:
if(event.getKeyCode() == KeyEvent.KEYCODE_DEL){
super.dispatchKeyEvent(event);
focusPreviousET();
return true;
}
else{
super.dispatchKeyEvent(event);
check();
return true;
}
private void focusPreviousET() {
String sId = getId(getCurrentFocus());
Identification id = new Identification(sId);
etX = getETFromResource(id);
if(isEmpty(etX)){
etX.setEnabled(false);
id.previousId();
etX = getETFromResource(id);
etX.requestFocus();
}
}
public void check(){
etX = (EditText) getCurrentFocus();
if(etX.getText().toString().length()==2){
focusNextFreeET();
}
}
Also check() method doesn't work, and i don't know why... Method focusNextFreeET() works in other cases, but not here.
Any suggestions?
EDIT
Forgot to mention, cursor is actually located at the end when the EditText is filled with numbers like 22,31,10, and cursor is located at the beggining when the number has a 0 in front of it, like 01,02, etc... In both cases, keyboard is hidden.
Use these lines after focusing next item to open a keyboard
InputMethodManager inputMethodManager=(InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.toggleSoftInputFromWindow(yourEditText.getApplicationWindowToken(), InputMethodManager.SHOW_FORCED, 0);

How to change keyboard view in android after pressing any key

I have an Edittext field and want the user to be able to enter the text very quickly. The text that will be entered begins with a capital letter followed by a set of numbers only. So after entering the first letter I want the keyboard view to switch to show numbers only. Here is my code for the edittext listener:
final EditText carPlate=(EditText) findViewById(R.id.carPlateNumber);
carPlate.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
if(carPlateCharnum==0){
carPlate.setInputType(InputType.TYPE_CLASS_NUMBER);
carPlateCharnum++;
return true;
}
// if keydown and "enter" is pressed
if ((event.getAction()==KeyEvent.ACTION_DOWN)
&& (keyCode==KeyEvent.KEYCODE_ENTER)) {
// display a floating message
DisplayToast(carPlate.getText().toString() + carPlateCharnum);
carPlateCharnum++;
return true;
}
return false;
}
});
The problem is the keyboard view is only switching after I press the enter key. So I need to know where and how to put this part of code:
if(carPlateCharnum==0){
carPlate.setInputType(InputType.TYPE_CLASS_NUMBER);
carPlateCharnum++;
return true;
}
Also I don't want the insertion point to return to the beginning of the EditText field after entering the first letter.
The keyboard has to reinitialize itself to be informed about the changes in the EditText carPlate.
(Detail-Info: TextView.onCreateInputConnection() returns the new InputType to the InputMethodManager).
carPlate.setInputType(InputType.TYPE_CLASS_NUMBER);
((InputMethodManager) YourActivity.this.getSystemService(Context.INPUT_METHOD_SERVICE))
.restartInput(carPlate);

combine text(or char) with user input in edittext for android

To All.
Right now i am working on App which launches a dialog(containing EditText) on any alphanumeric key pressed from keyboard. Now i want that whatever user type should appear in EditText box, which is working properly the only issue that i have is, i want the char key which was 1st pressed to open dialog in EditText Box. I am missing the 1st char key which is obviously right. But I retrieve that char as string separately.
Now wanted to attach(show) that char key to inputted EditText from user as 1st letter.
I tried this,
{
final EditText search_d_text = (EditText) dialog
.findViewById(R.id.search_text1);
search_d_text.setText(s1);// si is the 1st char key launch dialog(containing edittext).
search_d_text.setInputType(InputType.TYPE_NULL);
search_d_text
.setOnEditorActionListener(new OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId,
KeyEvent event) {
if (event != null
&& event.getAction() == KeyEvent.ACTION_DOWN) {
// Handle enter key
return true;
}
if (actionId == EditorInfo.IME_ACTION_NEXT) {
// Handle IME NEXT key
return true;
}
if (actionId == EditorInfo.IME_ACTION_DONE) {
// Handle IME DONE key
return true;
}
return false;
}
});
search_string = search_d_text.getText().toString();
enterd_text = search_d_text.getText();
// collecting input text.
}
What i am getting is eg. when i type MASK, It shows ASKM.
The setText(s1) is always act as last letter.
I want to show the word or whatever user input starting from 1st key.
Thank You.
Found solution ,
Just moved edit text cursor position. By
search_d_text.setSelection(s1.length()); i.e to next position.

EditText Minimum Length & Launch New Activity

I have a couple of queries regarding the EditText function in Android.
First of all, is it possible to set a minimum number of characters in the EditText field? I'm aware that there is an
android:maxLength="*"
however for some reason you can't have
android:minLength="*"
Also, I was wondering if it is possible to launch a new activity after pressing the enter key on the keyboard that pops us when inputing data into the EditText field? And if so, could someone show me how?
Thanks for any help you could offer regarding either question :)
To respond to an enter key in your edit field and notify the user if they haven't entered enough text:
EditText myEdit = (EditText) findViewById(R.id.myedittext);
myEdit.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {
if (myEdit.getText().length() < minLength) {
Toast.makeText(CurrentActivity.this, "Not enough characters", Toast.LENGTH_SHORT);
} else {
startActivity(new Intent(CurrentActivity.this, ActivityToLaunch.class);
}
return true;
}
return false;
}
});
There's no simple way to force a minimum length as the field is edited. You'd check the length on every character entered and then throw out keystrokes when the user attempt to delete past the minimum. It's pretty messy which is why there's no built-in way to do it.

Android EditText : getting entered text

I want to get the after entered text.I have done using TextWatcher.
There are some issues:
For example I want to enter 32.5. In that method I want to add to SET<Product>.
Here each & every number its saving object.That means after enter 3 its add Product object into SET, then add 2 then also adding...
I want to avoid. Once I finish enter EditText,Then want to take it:
final EditText txtQty = new EditText(this);
txtQty.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
Log.v("TAG", "afterTextChanged" + s.toString());
String enterdPrice = txtPrice.getText().toString();
double remainQty =0.00;
Product enterdProduct = new Product();
try{
String enteredQty = s.toString();
enterdProduct.setProductCode(txtCode.getText().toString());
enterdProduct.setPrice(Double.parseDouble(enterdPrice));
//enterdProduct.setQty(Double.parseDouble(enteredQty));
// TO-DO
if (productSet.contains(enterdProduct)) {
productSet.remove(enterdProduct);
}
productSet.add(enterdProduct);
System.out.println("SIZE --" + productSet.size());
}
catch (Exception e) {
e.printStackTrace();
}
});
Please give me idea, How we can get the EditText once enter I enetred text?
You can get entered text on pressing "Enter" button on keyboard.
final EditText edittext = (EditText) findViewById(R.id.edittext);
edittext.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
// If the event is a key-down event on the "enter" button
if ((event.getAction() == KeyEvent.ACTION_DOWN) &&
(keyCode == KeyEvent.KEYCODE_ENTER)) {
// Perform action on key press
return true;
}
return false;
}
});
Code from Android tutorial
Can't you use a separate button to add an object using the value in EditText?
Extend the EditText class and override onEndBatchEdit to implement the saving functionality after it has been edited in a 'batch' (could implement some sort of listener interface).

Categories

Resources