I have an EditText field which I would like to introduce some sort of Auto-Fill feature on. All I am currently trying to do is fill the the EditText box with "Special CT" if the "S" button is pressed. This is what I have:
ctEditText = (EditText) findViewById( 1001 );
ctEditText.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
Log.i( "KEY", "PRESSED" );
// if keydown and "enter" is pressed
if ((event.getAction() == KeyEvent.ACTION_DOWN)
&& (keyCode == KeyEvent.KEYCODE_ENTER)) {
return true;
} else if ((event.getAction() == KeyEvent.ACTION_DOWN)
&& (keyCode == KeyEvent.KEYCODE_S)) {
Log.i( "KEY", "S" );
if( ctEditText.getText().toString().length() == 1 ) {
ctEditText.setText( "Special CT" );
}
return true;
}
return false;
}
});
With this code, pressing the "S" button does absolutely nothing for me. My LogCat does not show either of my LogCalls until I press the enter button in the bottom right of the keyboard. And when I press the enter button, it displays the KEY PRESSED log call twice, no matter how many different keys I have pressed prior to the enter button.
EDIT
So after messing around with it some more I have realized that the reason the Log call appears twice is because it is appearing when I release the enter key as well. I also got the S key to call the KEY PRESSED log call but it is still not recognized in my If statement.
Try this:
ctEditText = (EditText) findViewById( 1001 );
ctEditText.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
Log.i( "KEY", "PRESSED" );
// if keydown and "enter" is pressed
if (ctEditText.getText().toString().equalsIgnoreCase("S")) {
Log.i( "KEY", "S" );
ctEditText.setText( "Special CT" );
return true;
}
else if ((event.getAction() == KeyEvent.ACTION_DOWN)
&& (keyCode == KeyEvent.KEYCODE_ENTER)) {
return true;
}
return false;
}
});
just check that the Text entered is equal to "S"
if (ctEditText.getText().toString().equalsIgnoreCase("S"))
Even better, you can use TextWatcher example
Related
I have a KeyListener on an editText like so:
tip = (EditText) findViewById(R.id.tip);
tip.setOnKeyListener(new EditText.OnKeyListener(){
public boolean onKey(View v, int keyCode, KeyEvent event) {
Log.i("debug123", "onKeyListener. event.getKeyCode(): " + event.getKeyCode());
// If the event is a key-down event on the "enter" button
if ((event.getAction() == KeyEvent.ACTION_DOWN) && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) {
checkInput();
return true;
}
return false;
}
});
But no softkeyboard-stroke is recognised.?
Only when I left the Activity with the BACK-Button (HardwareButton) the Listener recognises the action.
But from all that I read, this is the way to go if I want to work with user-input at a EditText.
setOnKeyListener
Register a callback to be invoked when a hardware key is pressed in
this view. Key presses in software input methods will generally not
trigger the methods of this listener.
setOnEditorActionListener
Set a special listener to be called when an action is performed on the
text view. This will be called when the enter key is pressed, or when
an action supplied to the IME is selected by the user.
To solve your problem using setOnEditorActionListener, please check below:
Add imeOptions and inputType to your EditText
<EditText
android:id="#+id/tip"
android:imeOptions="actionDone"
android:inputType="text"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
Then add setOnEditorActionListener to EditText
tip.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if ( (actionId == EditorInfo.IME_ACTION_DONE) || (event.getKeyCode() == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN) ) {
checkInput();
return true;
} else {
return false;
}
}
});
Here,
actionId == EditorInfo.IME_ACTION_DONE handle action from Soft Keyboard (IME)
event.getKeyCode() == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN handle enter key from Hardware Keyboard
Hi I am working with Text Editor in my android app. I want the cursor to move to next line in edittext when i touch enter key in android-softkeyboard and have to execute a method,so i used setOnKeyListener() because when i pressed the key it goes to this method and execute myMethod().
My main problem is when ever i used this (edittext.setInputType(InputType.TYPE_CLASS_TEXT);) line of code it is entering into the setOnKeyListener() method and executes myMethod well but the cursor position is still in same line,if i removed that line the cursor position is updating (goto next line) but setOnKeyListener() is not executing.
Please suggest me how to work on it ,My code is
edittext = (EditText) findViewById(R.id.editText);
edittext.setInputType(InputType.TYPE_CLASS_TEXT);
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)) {
Toast.makeText(MainActivity.this, edittext.getText(), Toast.LENGTH_SHORT).show();
myMethod();
return true;
}
return false;
}
});
Thanks in advance.
Try return "false":
if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {
Toast.makeText(MainActivity.this, edittext.getText(), Toast.LENGTH_SHORT).show();
myMethod();
return false; // here
}
i have been using dispatchKeyEvent to get the keycode of android keyboard but the problem is when i tap on Sym or Emoji button nothing happen, no keycode shows. this is the code i use to get the keycode:
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
Toast.makeText(getBaseContext(), "key pressed : "+ String.valueOf(event.getKeyCode()), Toast.LENGTH_SHORT).show();
return super.dispatchKeyEvent(event);
}
Use KeyEvent.KEYCODE_PICTSYMBOLS for emoji.
/*
* Respond to soft keyboard events, look for the DONE press on the password field.
*/
public boolean onKey(View v, int keyCode, KeyEvent event)
{
if ((event.getAction() == KeyEvent.ACTION_DOWN) &&
(keyCode == KeyEvent.KeyEvent.KEYCODE_PICTSYMBOLS))
{
// Done pressed! Do something here.
}
// Returning false allows other listeners to react to the press.
return false;
}
I have an edit text which functions as a search box in my application. In Jelly Bean on my Nexus 7 when I type something into the text box which I am listening on and hit enter the KeyEvent = null and ActionId = 0 passed into the onEditorAction() method. Has anyone else encountered this? I'm thinking it might be a bug.
In the second if statement below I get a null pointer because the actionId = 0 and KeyEvent = null;
// Search field logic.
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
Log.d(TAG, "onEditorAction");
if (event != null && event.getAction() != KeyEvent.ACTION_DOWN)
return false;
if (actionId == EditorInfo.IME_ACTION_SEARCH
|| event.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
.....Do some stuff();
}
}
Ended up adding in a null check for KeyEvent. Thanks to commonsware for pointing out this happens on 3.0+. Seems more like a workaround then a solution, but it works.
// Search field logic.
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
Log.d(TAG, "onEditorAction");
if (event != null && event.getAction() != KeyEvent.ACTION_DOWN) {
return false;
} else if (actionId == EditorInfo.IME_ACTION_SEARCH
|| event == null
|| event.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
.....Do some stuff();
}
}
I found that my "bug-like behavior" was due to imeActionLabel complicating things. I only used it because it was mentioned in the Text Fields Guide as a way to have a custom return key label. Here are the results of my tests in Lollipop,
Case 1: default, return key symbol = closing angle bracket
<EditText
android:singleLine="true"
android:inputType="textUri"/>
onEditorAction is called once.
KeyEvent = null, actionId = 5 = EditorInfo.IME_ACTION_NEXT
if return true, cursor remains in EditText, keyboard open
if return false, cursor moves to next focusable, keyboard open if
necessary
Case 2: imeOptions, return key symbol = checkmark
<EditText
android:singleLine="true"
android:inputType="textUri"
android:imeOptions="actionDone"/>
onEditorAction is called once.
KeyEvent = null, actionId = 6 = EditorInfo.IME_ACTION_DONE
if return true, cursor remains in EditText, keyboard open
if return false, cursor remains in EditText, keyboard closes
Case 3: imeActionLabel, return key symbol = "URdone"
<EditText
android:singleLine="true"
android:inputType="textUri"
android:imeOptions="actionDone"
android:imeActionLabel="URdone"/>
onEditorAction can be called more than once.
KeyEvent = null, actionId = 0
if return true, cursor remains in EditText, keyboard open, onEditorAction is NOT called a second time
if return false, onEditorAction is called a SECOND time:
KeyEvent = KeyEvent.ACTION_DOWN, actionId = 0
if return false, cursor moves to next focusable, keyboard open if necessary, onEditorAction is NOT called a third time
if return true, onEditorAction is called a THIRD time:
KeyEvent = KeyEvent.ACTION_UP, actionId = 0
if return true, cursor remains in EditText, keyboard open
if return false, cursor moves to next focusable, keyboard open if necessary
NOTES:
I'm not sure if actionId = 0 is from EditorInfo.IME_ACTION_UNSPECIFIED or EditorInfo.IME_NULL.
If the next focusable is non-editable, the return key symbol becomes a left pointing arrow.
You can also use setOnFocusChangeListener to override onFocusChange, which will be called according to the above cursor behavior.
Beside KeyEvent.ACTION_UP we also need to capture KeyEvent.ACTION_DOWN. Unless KeyEvent.ACTION_UP will never be passed to EditText so our onEditorAction will not work.
Example:
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
final boolean isEnterEvent = event != null
&& event.getKeyCode() == KeyEvent.KEYCODE_ENTER;
final boolean isEnterUpEvent = isEnterEvent && event.getAction() == KeyEvent.ACTION_UP;
final boolean isEnterDownEvent = isEnterEvent && event.getAction() == KeyEvent.ACTION_DOWN;
if (actionId == EditorInfo.IME_ACTION_DONE || isEnterUpEvent ) {
// Do your action here
performLogin();
return true;
} else if (isEnterDownEvent) {
// Capture this event to receive ACTION_UP
return true;
} else {
// We do not care on other actions
return false;
}
}
You have to replace EditorInfo.IME_ACTION_DONE to correct version of EditorInfo.IME_ACTION_ according to android:imeOptions="actionNext"
It might be worth noting, that you can get more than one event for the click on Enter (depending on the android version). One for the KeyDown (KeyEvent.ACTION_DOWN), one for the KeyUp (KeyEvent.ACTION_UP). When I forgot to check that I accidentally started two server calls for the same action.
searchBox.setOnEditorActionListener(new OnEditorActionListener() {
// enter key in search box triggers search
#Override
public boolean onEditorAction(TextView v, int actionId,
KeyEvent event) {
if ((event != null && event.getAction() == KeyEvent.ACTION_UP) || event==null) {
onSearchButtonClicked();
}
return true;
}
});
You dont discover the truth, if you customize return key. You need both set imeActionLabel and imeActionId in your layout. Such as:
imeActionLabel="xxxx"
imeActionId = "6"
In your java code:
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
doSomeThing();
return true;
}
return false;
}
It will work fine.
The action id is set to 0 by default for any enter event.
From the Android documentation:
actionId
int: Identifier of the action. This will be either the identifier you supplied, or EditorInfo#IME_NULL if being called due to the enter key being pressed.
So the proper way to handle enter key events would be:
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_NULL) {
// Handle return key here
return true;
}
return false;
}
Hello
I've got a searched EditText and search Button. When I type the searched text, I'd like to use ENTER key on softkeyboard instead of search Button to activate search function.
Thanks for help in advance.
You do it by setting a OnKeyListener on your EditText.
Here is a sample from my own code. I have an EditText named addCourseText, which will call the function addCourseFromTextBox when either the enter key or the d-pad is clicked.
addCourseText = (EditText) findViewById(R.id.clEtAddCourse);
addCourseText.setOnKeyListener(new OnKeyListener()
{
public boolean onKey(View v, int keyCode, KeyEvent event)
{
if (event.getAction() == KeyEvent.ACTION_DOWN)
{
switch (keyCode)
{
case KeyEvent.KEYCODE_DPAD_CENTER:
case KeyEvent.KEYCODE_ENTER:
addCourseFromTextBox();
return true;
default:
break;
}
}
return false;
}
});
<EditText
android:id="#+id/search"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="#string/search_hint"
android:inputType="text"
android:imeOptions="actionSend" />
You can then listen for presses on the action button by defining a TextView.OnEditorActionListener for the EditText element. In your listener, respond to the appropriate IME action ID defined in the EditorInfo class, such as IME_ACTION_SEND. For example:
EditText editText = (EditText) findViewById(R.id.search);
editText.setOnEditorActionListener(new OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
boolean handled = false;
if (actionId == EditorInfo.IME_ACTION_SEND) {
sendMessage();
handled = true;
}
return handled;
}
});
Source: https://developer.android.com/training/keyboard-input/style.html
may be you could add a attribute to your EditText like this:
android:imeOptions="actionSearch"
add an attribute to the EditText like
android:imeOptions="actionSearch"
this is the best way to do the function
and the imeOptions also have some other values like "go" 、"next"、"done" etc.
Most updated way to achieve this is:
Add this to your EditText in XML:
android:imeOptions="actionSearch"
Then in your Activity/Fragment:
EditText.setOnEditorActionListener { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
// Do what you want here
return#setOnEditorActionListener true
}
return#setOnEditorActionListener false
}
We can also use Kotlin lambda
editText.setOnKeyListener { _, keyCode, keyEvent ->
if (keyEvent.action == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_ENTER) {
Log.d("Android view component", "Enter button was pressed")
return#setOnKeyListener true
}
return#setOnKeyListener false
}
To avoid the focus advancing to the next editable field (if you have one) you might want to ignore the key-down events, but handle key-up events. I also prefer to filter first on the keyCode, assuming that it would be marginally more efficient. By the way, remember that returning true means that you have handled the event, so no other listener will. Anyway, here is my version.
ETFind.setOnKeyListener(new OnKeyListener()
{
public boolean onKey(View v, int keyCode, KeyEvent event)
{
if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER
|| keyCode == KeyEvent.KEYCODE_ENTER) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
// do nothing yet
} else if (event.getAction() == KeyEvent.ACTION_UP) {
findForward();
} // is there any other option here?...
// Regardless of what we did above,
// we do not want to propagate the Enter key up
// since it was our task to handle it.
return true;
} else {
// it is not an Enter key - let others handle the event
return false;
}
}
});
this is a sample of one of my app how i handle
//searching for the Edit Text in the view
final EditText myEditText =(EditText)view.findViewById(R.id.myEditText);
myEditText.setOnKeyListener(new View.OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN)
if ((keyCode == KeyEvent.KEYCODE_DPAD_CENTER) ||
(keyCode == KeyEvent.KEYCODE_ENTER)) {
//do something
//true because you handle the event
return true;
}
return false;
}
});