I want to build a instant searchview, which will show the search result immediately in the same layout as soon as a user input anything. So I am googling and decide to use onQueryTextChange to implement that. However I cannot figure out how to "fire" a intent like the normal result which pressing ENTER will lead to, to tell my Activity that there is an event that a user have input something in searchview and you(Activity) should handle it.
Any idea to help?
If I understood you correcty you want to recognize KEY_EVENT (ENTER). I've ended with custom EditText styled like original SearchView, then used OnEditorActionListener:
queryEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEARCH ||
(event != null && event.getKeyCode()==KeyEvent.KEYCODE_ENTER)) {
performSearch();
return true;
}
return false;
}
});
SearchView don't have setOnEditorActionListener method, thats why I'm using simple EditText
note EditorInfo.IME_ACTION_SEARCH option inside "if", you may request "special" keyboard layout with magnify icon instead of Enter key (but remember that not all keyboards are supporting this option and custom keyboard app may show "usual" layout of keyboard)
android:inputType="text|textNoSuggestions"
android:imeOptions="actionSearch"
i'm working on a project wich require the use of a custom soft keyboard developed by some one else. The problem is that the setOnEditorActionListener does not work in a specific windows where a fragment is used. Does not work means that the onEditorAction is not fired at all. The problem appens only with the custom keyboard, with the default one every thing is working well. The problem is that the soft keyboard project is very complex because i don't know soft keyboard logics and I need to solve the problem before tomoroow morning. Does anyone have an idea of this behavior? Please help
this is the part where i set the listener, this code is working all around the project but here, even the first listener's line is not reached
((EditText) getView().findViewById(R.seatDetailCommonHeader.txtName)).setOnEditorActionListener(new OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (event != null && event.getAction() != KeyEvent.ACTION_DOWN) {
return true;
}
// KeyboardHelper.setKeyboardVisibilty(v, false);
executeCheck();
return true;
}
});
i went into further investigations, i put a breakpoint on every method's first line in the keyboard code (which is the one taken from the sdk samples with just some layout modification) and the same EditText in two different activities fires different methods:
in one case (the working one) this methods are fired when action button is clicked:
LatinKeyboard.isInside
LatinKeyboard.isInside
LatinKeyboard.isInside
LatinKeyboard.isInside
LatinKeyboard.isInside
LatinKeyboard.isInside
LatinKeyboard.isInside
LatinKeyboard.isInside
LatinKeyboard.isInside
SoftKeyboard.onKey
SoftKeyboard.isWordSeparator
SoftKeyboard.sendKey
SoftKeyboard.keyDownUp
SoftKeyboard.keyDownUp
SoftKeyboard.updateShiftKeyState
in the other case (the one that is not working) the same methods are fired, plus these:
SoftKeyboard.onFinishInput
SoftKeyboard.onStartInput
SoftKeyboard.updateShiftKeyState
LatinKeyboard.setImeOptions
SoftKeyboard.onStartInputView
hope someone has some idea of this behavior because i'm really in trouble
I have 6 Edittexts grouped in 6 differents layouts, all in the same view.
My problem is that my app is forced to landscape mode, and by pressing the 'next' button i want to automatically start to edit another editText rather than the one android set me by default. Example: i'm writing on EditText1, press next, and focus is taken by the EditText that is UNDER the 1st one. I want to edit the one that is RIGHT to it.
Sorry for my bad english :(
The device is a galaxy tab, with Google API8/Android 2.2
Thanks
Haven't tested it, but this should work
some_edittext.setOnEditorActionListener(new OnEditorActionListener() {
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_NEXT) {
some_button.performClick();
return true;
}
return false;
}
});
I might be wrong but I don't think there is any implicit way of doing it. You would need to write your own EditorAction.
You need to monitor everything that the user enters and whenever he presses 'NEXT', you would have to manually shift the focus to the next EditText, using EditorInfo.IME_ACTION_NEXT.
Doing a simple override in my base activity of onKeyDown, I'm able to capture all key presses except those of the enter and dpad center buttons (as determined via breakpoint). I've no clue as to why - can anyone shed some light on the situation?
EDIT: Quick update - it does capture Dpad center and enter key LONG presses, but still not normal presses.
I know this question is already pretty old but in case some desperate coder got lost I post my answer.
I had a similar problem with my USB keyboard. When anything else except a EditText box was focussed the ENTER key was never caught by onKeyUp or onKeyDown.
if you use dispatchKeyEvent() you get the KeyEvent before it reaches the window and in my case I definitely get the ENTER key.
But cautious, the event is called twice, once for key down and once for key up.
here a sample code:
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
System.out.println(event.getAction() + " " + event.getKeyCode() + " - " + (char) event.getUnicodeChar());
return true;
}
Did you read the documentation?
Key presses in software keyboards will generally NOT trigger this listener, although some may elect to do so in some situations. Do not rely on this to catch software key presses.
Also, your way of capturing keys is very vague. You are not even checking the keyCode sent to you by using:
#Override public boolean onKeyDown(int keyCode, KeyEvent event) { return false; }
You can handle onKey from a View:
public boolean onKey(View v, int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_ENTER:
/* This is a sample for handling the Enter button */
return true;
}
return false;
}
Remember to implement OnKeyListener and to set your listener
viewname.setOnKeyListener(this);
it appears that DPAD keys are acting for the focused items as have been told here:
https://groups.google.com/forum/#!topic/android-developers/HsILBlpsK7I
Although I haven't tried it myself, maybe you can set focus to your view object and attach a key listener function on it.
Update: My colleague had the same problem and this suggestion worked for her. :) She was able to catch the key code from DPAD when the list view is focused.
We are working on our first android app and it has been a very enjoyable experience so far. It is almost complete, but before release we are having some considerations ,mainly about android soft keyboard.
We have a couple of EditText fields that are used to enter numbers. We would like to capture the event when user presses enter, and do some calcuations and saving on this callback.
The problem is that we are not getting a fixed event as different phones have different keyboards. Some have 'Done' button and our HTC phones have 'Enter' buttons. We tried using the imeOptions as 'done' but that had no effect on the HTC phones.
We also know that the keyboard can be dismissed by hitting the back button. So my question is if there is a reliable way to know when the user has stopped entering or when the keyboard is hidden, just like textFieldShouldReturn callback in iphone sdk(which will always fire when keyboard goes down, independent of what key caused it to go down)..
In other words, how an android developer handles soft keyboard? I check for KeyEvent.KEYCODE_ENTER on editText onClick() event and do my tasks there.It is working on my HTC android, but not on my friends Nexus phone, which has a done button instead of enter. There onClick is not even called. How a developer handles this?
EDIT: After losing half of my hair, and with the help of some good friends here
I have tried all your suggestions but at the end by using onEditorActionListener along with onKeyListener method did the trick for me. In onEdit callback of onEditorActionListener I checked for KeyCode ACTION_DONE, which did get called on keyboards with done button. On keyboards which has enter onKey gets called. In onKey method I checked for KEYCODE_BACK also, so that hardware back press event also can be handled. I haven't yet found out a android device with done and enter on the keyboard (seriously), still I even handled that case with a flag. Thanks #Femi for suggesting onEditorActionListener, and thanks for all friends for your help. But the answer to my original question
Q: Is there an reliable and easier way to know android soft keyboard resigns (callback that works on every phone)
Ans : No, All methods suggested here and all methods suggested on other sites are not straightforward. And I think handling an event for keyboard return key is the most basic thing for any operating system. Google, are you there?
Since it seems that you are catching the KEYCODE_ENTER event, you might be able to use this: http://developer.android.com/reference/android/widget/TextView.html#setOnEditorActionListener%28android.widget.TextView.OnEditorActionListener%29. In theory this will let you detect whatever the input method end action is (whether its back, done, enter, or whatever) and respond to it.
Let me know if that works for you.
Wouldn't you also need to perform those calculations when the user is leaving the TextView on a hardware keyboard? I wouldn't focus on the keyboard, but on the TextView itself. If so, what you probably want is setTransformationMethod
You'd have to implement a custom TransformationMethod, specifically the method getTransformation, which transforms a source CharSequence into another one. You can then use the onFocusChanged to apply this only when the focus is lost for that TextView.
I found a solution on this SO page:
Intercept back button from soft keyboard
The answer from mhradek has 0 votes but it seems to be working.
The idea is to extend the base layout of your activity so that you can override the dispatchKeyEventPreIme method and do what you want regarding the KeyEvent passed. Note that you are responsible for managing the soft keyboard.
I am using it and I can definitely intercept key strokes (the back button for example) without the soft keyboard "eating" them. I have yet to play more with it in order to see what is possible and what is not.
I hope it helps.
Have you tried implementing custom EditText view, where you override dispatchKeyEventPreIme? Just like in answer posted by Arnaud (referencing Intercept back button from soft keyboard) but instead of using custom layout use custom EditText and override:
#Override
public boolean dispatchKeyEventPreIme(KeyEvent event) {
if(KeyEvent.KEYCODE_BACK == event.getKeyCode()) {
//this hides soft keyboard in super.dispatchKeyEventPreIme(event)
}
return super.dispatchKeyEventPreIme(event);
}
I suggested this solution in this question
I cant believe Google doesnt have a keyboard independant callback for this case
Wow, I cant believe that neither. I am having a similar problem at the moment.
In addition to the IME ACTION I check for focus changes on the EditFields. This is fine for most of the time, but won't work always.
I found a way to be notified when the keyboard is being hidden, but it's not a complete solution yet (and I'm not sure whether it's a good idea), but I don't have the time to continue right now, so I thought I can drop the start of the idea here...:
Write your own EditText(extend EditText) and override onCreateInputConnection. In your onCreateInputConnection return your own implementation of InputConnection (you can simply extend BasicInputConnection.
The InputConnections "finishComposingText()" method is always called when the keyboard is being hidden (also when the user presses the back-key).
This is the code, and maybe someone else has an idea, why the entered text is not shown in this editfield ;-)
public class MyEditText extends EditText{
public MyEditText(Context context) {
super(context);
}
public MyEditText(Context context, AttributeSet attrs) {
super(context);
}
public MyEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
System.out.println("onCreateInputConnection, "+outAttrs.actionId);
return new MyInputConnection(this,true);
}
private class MyInputConnection extends BaseInputConnection{
public MyInputConnection(View targetView, boolean fullEditor) {
super(targetView, fullEditor);
}
#Override
public boolean finishComposingText() {
System.out.println("FINISH");
return super.finishComposingText();
}
}
}
JPM
I have not tried this but, reading the documentation, it seems possible.
// From an activity, you can call
if (getResources().getConfiguration().keyboardHidden == Configuration.KEYBOARDHIDDEN_YES) {
// your code here
}
This code is working fine for me with HTC and default Android keyboard:
editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
// handle enter key on keyboard
if (actionId == EditorInfo.IME_ACTION_SEND ||
(event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN)) {
if (uid != null) {
// hide keyboard
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
// perform other stuff
return true;
}
}
return false;
}
});
Using the following in the editText´s XML:
android:imeOptions="actionSend"
Of course you could also use something else like send, just make sure to change it in both the XML and Java code.