I would like to implement an EditText that operates similarly to the android alarm app. In this app, there are two EditText fields that serve as the HH and mm. Typing in these fields overwrites the number that was previously there. When you have typed the second number into the HH field, focus automatically switches to the mm field.
I have tried to put this logic in manually using a TextWatcher in the afterTextChanged() method, but unfortunately modifying the text whilst in this method causes a recursive loop.
What's the correct way to implement this?
See below for alarm app example:
add listener to your hh text view like this
hh.setOnKeyListener(new OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (hh.getText().toString().length() == 2){
mm.requestFocus();
}
return false;
}
});
hope this will work for you.
It turns out editing the text from the onTextChanged method doesn't actually cause a recursive loop, as long as you temporarily disable the logic with a boolean switch. Painstakingly wrote in all the logic into the TextWatcher to mimic the alarm-style EditText fields.
Related
I have a set of custom edit controls, each of them assigns a value to a variable in my app, when losing focus. However when a user presses Next on the numeric pad, my control doesn't get a lost focus notification and an associated variable isn't set.
All variables should be set at runtime, exactly when a user changes values, so I cannot just wait till the numeric pad is closed and then update them all.
I also cannot set my variables in control's text change listener, it is a very costly operation, I prefer to do it when a user completes typing.
So my only option seems to be listening on the Next button, but I cannot find any mention of this anywhere.
Try this code:
yourEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_NEXT)
//do what you want
return false;
}
});
This is what I intend to do:
I have an activity which have 20-25 EditText. When an EditText's text changes some corresponding TextView's text has to be changed. i.e. user inputs his monthly expenditure for groceries so the TextView which shows his yearly expenditure for grocery gets updated and so does the total monthly and yearly expenditure TextView.
I know that I can do it with TextWatcher.But in that case I'll need a separate TextWatcher for each of the EditText. Even if I write a custom TextWatcher which holds the EditText's Id and does the operation appropriate within a switch-case block but in that case I'll need a new instance of that class for each EditText. Isn't that very inefficient and memory consuming?
I was hoping to have something like the OnClickListener so that I would only have to Override some functions and it will do all the tasks like for all the Buttons in my Activity I just have to override the onClick(View v) function and its done. Is there a way to accomplish this?
How about something like this:
yourEditText1.setOnFocusChangeListener(yourFocusChangeListener);
yourEditText2.setOnFocusChangeListener(yourFocusChangeListener);
View.OnFocusChangeListener yourFocusChageListener = new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
// Update your textview depending on which edittext lost focus
}
}
});
The benefit to this over a TextWatcher (IMO) is that you know the user is done since they have navigated away from the EditText. The only issue is that they need to navigate away for it to fire (not sure if that would be a showstopper for you or not).
You can't avoid using a TextWatcher to "see" the input events on your EditText. Some time ago I answered a similar question, with a small modification you could probably use it to make things easy. In that class from my answer you would probably need to modify the onInputChange() method to also return the id of the EditText so you know who triggered the text input.
When onKeyListener is set Backspace/delete key is not functioning.
I set an OnKeyListener on my EditText. Then default actions of some keys became not functioning. Like DELETE/Backspace. Then I changed to use my own text-deleting function by manipulating the string inside. But it seems to be pretty complex.
I have to get selection, make substring, and so on. Are there other solutions to get the key functioning normally?
It depends on the IME you are using.
Some IME implements delete function without sending KEYCODE_DEL.
Try other IME than the default.
For example, if you press DEL button long enough, some IME deletes all text in the edit box.
This cannot be done through KEYCODE_DEL.
I had this problem too, I solved it by returning false in onKeyListener function. This should execute normal operations on other keys.
.setOnKeyListener(new DialogInterface.OnKeyListener()
{
#Override public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event)
{
//your workarounds;
return false;
}
})
There are two known issues affecting KEYCODE_DEL for the default (LatinIME) Google Keyboard that ships with Android: Issues 42904 and 62306.
I have researched this and have devised a workaround, with code, that seems to get around both of these issues. That workaround can be found here:
Android - cannot capture backspace/delete press in soft. keyboard
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:
Solution: One of your existing onkeylistener codes contain 'return true'. Rectify it by setting existing code from 'return true' to 'return false'
.setOnKeyListener(new View.OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
...
return false;
}
});
New to programming, now to android. So I hope I dont annoy you to much.
How would I go about setting an onkeylistener at the top level of the app that captured the keyevent no matter what.
Basically what i have is a linear layout with dynamically added edittexts.
I want to capture the Enter key event and have it get the current edittext, perform some tests then create a new edittext and add it to the layout.
I know I can (and have) implement an onkeylistener to individual child views, but not being a programmer, the logic seems weird to create an edittext that listens for input to create another edittext that listens for input to create another.... (you see where this goes)
Can anyone point me in the right direction?
I have lots more info about what Im trying to do, I just dont know what is pertinent and what is not, so let me know if you need more.
Thanks for your time in advance,
Chris
Take a look at http://developer.android.com/reference/android/app/Activity.html#dispatchKeyEvent%28android.view.KeyEvent%29
What you want is to intercept all the events before they are processed by any View in the window. Return true if the event was handled or false if you want the childs to process the event further.
Like Ben said your activity can implement OnKeyListener then for each EditText you create, set the OnKeyListener to be the activity.
editText1.setOnKeyListener(this);
And then in your implementation of onKey you can handle the key press event.
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if(v == editText1) {
// do something
} else if( v == editText2 ) {
// do something
}
return true; // return true if you handled the keypress
}
Your activity can implement OnKeyListener.
I have copied Android's NumberPicker widget to my own application, but I'm having one problem...
When someone manually clicks the EditText and changes it via the keyboard, the selection is not saved. Is there some listener that I can implement to check and see if the user manually changes the EditText to set it as current? Or something?
I found this solution lost somewhere in android-developers google group:
For android SDK NumberPicker widget, simply use:
myNumberPicker.clearFocus();
before you try to get its value.
When you have an activity with only the NumberPicker and maybe a button or a spinner, and you edit it and try to click elsewhere, its onFocusChangedListener is not handled properly. So you just need to force it to lost focus before using getValue(). Worked like a charm to me.
I used the Michael Novak number picker. Although onEditorAction was already implemented it didn't properly set the input. The easy fix for me was to call validateInput on the textView in getCurrent.
/**
* #return the current value.
*/
public int getCurrent() {
validateInput(mText);
return mCurrent;
}
I has same problem using numberpicker http://www.quietlycoding.com/?p=5 and I solved it by adding OnKeyListener (instead OnEditorActionListener which was already suggested by Junzi) to NumberPicker class. Other steps are same so:
Let NumberPicker.java extend OnKeyListener
add mText.setOnKeyListener(this); to NumberPicker constructor
implement OnKey:
public boolean onKey(View v, int keyCode, KeyEvent event) {
validateInput(v);
return false;
}
If you are using Android NumberPicker from Android4.0.x means you can get the Value of NumberPicker using the getValue().
http://developer.android.com/reference/android/widget/NumberPicker.html#getValue()
It's an Easy way to get the Numberpicker in android 4.0.x...
final NumberPicker np = new NumberPicker(CustomizedListView.this);
np.setMinValue(0);
np.setMaxValue(100);
np.setWrapSelectorWheel(true);
And you can get the value by using np.getValue() method.
You can try to set a TextWatcher to your EditText to do the same or do not allow an user to enter a value manually there...
Or keep an OK button there and take the values out from the EditText only when an user clicks the OK button
Did you try this sample ?
http://www.quietlycoding.com/?p=5
Not sure if you are using the same Numberpicker as mine: http://www.quietlycoding.com/?p=5. I have tried to add a OnEditorActionListener to the NumberClass, seems it solved the problem for me.
modify the NumberPicker.java let it extends OnEditorActionListener.
add mText.setOnEditorActionListener(this); to NumberPicker constructor
implement onEditorAction:
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
validateInput(v);
return false;
}
Hope it can be helpful.