Detect back event on android keyboard - android

I have some intents inside a tab controller and for one of them I have an edit text which I need to know for sure when it has focus and when it loses this focus.
I have mapped most of the events like focus listener, OnEditorActionListener and so on, now my only problem that remains is that when I have focus the soft keyboard appears and I want to close it either:
1) by the done button and not by the back button on the phone (disable back button to close keyboard while the keyboard is visible)
2) detect the back button event while the keyboard is visible so that I can pass the focus to some other control.
I have tried multiple ways, but with no success, like onBackPressed, onConfigurationChanged (add hiddenKeyboard in the manifest), key_down on activity and so on, but no success.
Does anybody succeded this? Practically I want when the keyboard is visible and I press back on phone, my edit text to lose focus (otherControl.requestFocus -> which is a relative layout).

Old topic, but here is the expected answer
#Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
Toast.makeText(getContext(), "BACK", Toast.LENGTH_SHORT).show();
return true;
}
return super.onKeyPreIme(keyCode, event);
}
You should put this in a class that overrides EditText (class MyEditText extends EditText...)

Here is the way to capture back press key event: 1. Extent editText view to override onKeyPreIme
package com.test.test;
import android.content.Context;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.widget.EditText;
/**
* Created by sumit.saurabh on 11/10/16.
*/
public class ChatEditText extends EditText
{
/* Must use this constructor in order for the layout files to instantiate the class properly */
public ChatEditText(Context context, AttributeSet attrs)
{
super(context, attrs);
// TODO Auto-generated constructor stub
}
private KeyImeChange keyImeChangeListener;
public void setKeyImeChangeListener(KeyImeChange listener)
{
keyImeChangeListener = listener;
}
public interface KeyImeChange
{
public void onKeyIme(int keyCode, KeyEvent event);
}
#Override
public boolean onKeyPreIme(int keyCode, KeyEvent event)
{
if (keyImeChangeListener != null)
{
keyImeChangeListener.onKeyIme(keyCode, event);
}
return false;
}
}
2. ChatEditText in xml
<com.test.test.ChatEditText
android:id = "#+id/messageEditText"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
android:layout_gravity = "bottom"
android:layout_marginLeft = "12dp"
android:layout_marginRight = "30dp"
android:background = "#null"
android:hint = "Type your message"
android:inputType = "textMultiLine"
android:singleLine = "false"
android:textColorHint = "#c4c0bd"
android:textSize = "18sp"/>
3. Then attach a listener from anywhere like so:
private ChatEditText messageEditText;
messageEditText =
(ChatEditText) findViewById(R.id.messageEditText);
messageEditText.setKeyImeChangeListener(new ChatEditText.KeyImeChange(){
#Override
public void onKeyIme(int keyCode, KeyEvent event)
{
if (KeyEvent.KEYCODE_BACK == event.getKeyCode())
{
// do something
}
}});

here it is
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
if(event.getKeyCode() == KeyEvent.KEYCODE_BACK)
{ //do you back event work here
}
return super.dispatchKeyEvent(event);
}

Related

Edittext cursor still blinks after closing the soft keyboard

Is an edittext cursor supposed to continue blinking after the soft keyboard is closed or is this a result of testing on an emulator and wouldn't happen on an actual device? -- as pointed out by the second post in this discussion
Update:
I know that the edittexts still have the cursor blinking because they're still in focus -- logged a message whenever edittext lost focus, but message was never logged when soft keyboard closed.
Update:
I've tried doing:
#Override
public void onBackPressed() {
super.onBackPressed();
getCurrentFocus().clearFocus();
}
So that every time the keyboard is closed, the EditText currently in focus loses that focus and onFocusChanged() is called. The problem is that onBackPressed() isn't called when the back button is pressed when the keyboard is up. I know this because I put a toast in onBackPressed(), and no toast shows when the back button is pressed whilst the keyboard is up.
First create a custom Edit text. Below is the example which has a call back when keyboard back is pressed to dismiss the keyboard
public class EdittextListner extends EditText {
private KeyImeChange keyImeChangeListener;
public EdittextListner(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setKeyImeChangeListener(KeyImeChange listener) {
keyImeChangeListener = listener;
}
public interface KeyImeChange {
public boolean onKeyIme(int keyCode, KeyEvent event);
}
#Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (keyImeChangeListener != null) {
return keyImeChangeListener.onKeyIme(keyCode, event);
}
return false;
}
}
Secondly change your EditText to EdittextListner in you layout file.
Finally do the following
mLastNameEditText.setKeyImeChangeListener(new EdittextListner.KeyImeChange() {
#Override
public boolean onKeyIme(int keyCode, KeyEvent event) {
mLastNameEditText.clearFocus();
return true;
}
});
This worked for me. Hope this helps
Edittext is a View which accept input from user, so it is not related with keyborad open or close, when user will click on edittext, that edittext will get focus and cursor will start to blink for taking input,
So you can do one thing as when you are closing keyboard at the same time you can also set visibility of cursor for that edittext so it will stop to blink,
For that you need to write below line when you hide keyboard.
editTextObject.setCursorVisible(false);
This will stope cursor to blink.
As you said, the blinking cursor in the EditText is related to the EditText having focus, but showing or hiding the soft keyboard has no correlation to a View gaining or losing focus. Any View (EditText or otherwise) can be focused independent of whether or not a soft keyboard is showing and there is nothing intrinsic to EditText that would make it behave any differently.
If you want an EditText to lose focus whenever the soft keyboard is hidden, you will need to implement this functionality yourself by listening for changes in the soft keyboard visibility and updating the EditText as a result.
The only way to know keyboard is disappeared is to override
OnglobalLayout and check the height.
Based on that event you can "setCursorVisible(false)" on your edit text
For more information, check this Link.
RelativeLayout mainLayout = findViewById(R.layout.main_layout); // You must use the layout root
InputMethodManager im = (InputMethodManager) getSystemService(Service.INPUT_METHOD_SERVICE);
/*
Instantiate and pass a callback
*/
SoftKeyboard softKeyboard;
softKeyboard = new SoftKeyboard(mainLayout, im);
softKeyboard.setSoftKeyboardCallback(new SoftKeyboard.SoftKeyboardChanged()
{
#Override
public void onSoftKeyboardHide()
{
// Code here
EditText.clearFocus();
}
#Override
public void onSoftKeyboardShow()
{
// Code here
}
});
/*
Open or close the soft keyboard easily
*/
softKeyboard.openSoftKeyboard();
softKeyboard.closeSoftKeyboard();
/* Prevent memory leaks:
*/
#Override
public void onDestroy()
{
super.onDestroy();
softKeyboard.unRegisterSoftKeyboardCallback();
}
try this:
public class EditTextBackEvent extends EditText {
private EditTextImeBackListener mOnImeBack;
public EditTextBackEvent(Context context) {
super(context);
}
public EditTextBackEvent(Context context, AttributeSet attrs) {
super(context, attrs);
}
public EditTextBackEvent(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
if (mOnImeBack != null) mOnImeBack.onImeBack(this, this.getText().toString());
}
return super.dispatchKeyEvent(event);
}
public void setOnEditTextImeBackListener(EditTextImeBackListener listener) {
mOnImeBack = listener;
}
public interface EditTextImeBackListener {
void onImeBack(EditTextBackEvent ctrl, String text);
}
}
in your layout:
<yourpackagename.EditTextBackEvent
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
and in your fragment:
edittext.setOnEditTextImeBackListener(new EditTextBackEvent.EditTextImeBackListener()
{
#Override
public void onImeBack(EditTextBackEvent ctrl, String text)
{
edittext.clearfocus();
}
});
Try keeping a view in your layout which is focusable above your editText.
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:focusable="true"
android:focusableInTouchMode="true" />
This should work as the blank focusable view should catch focus and not your edittext.

How to make an app which will not listen to touch events

How to make an app which will not listen to touch events and back/home pressing but will listen only to the power button.
I've tried this but it wasn't successful.
#Override
public boolean onKeyDown(int keyCode, android.view.KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_POWER) {
return true;
}else if ((keyCode == KeyEvent.KEYCODE_HOME)|| (keyCode == KeyEvent.KEYCODE_BACK )){
return false;
}
return false;
}
You could wrap you class with a custom View of yours and override its OnClickListener and OnTouchListener methods. Override them with blank methods.
Also, keep your code to set how your app should work when the Power Button is clicked.
For instance, if you wrap your layout with a RelativeLayout or a general View, you could use something like
relativeLayout.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
return false;
}
});
relativeLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
return false;
}
});
To block user touch event try this solution. And if you want to disable back and home try to override this method of Activity:
#Override
public void onAttachedToWindow() {
this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
super.onAttachedToWindow();
}
three weeks ago, i want also to catch the home button, but i faied. i do some research, i find the android system don't support to modify it.you can visit this
Overriding the Home button - how do I get rid of the choice?, about homebutton.
as for the touchEvent, i advice you can try this method ,override onTouchEvent (if you dont add onTouchListener, make it retrun fasle and do nothing, at the same time ,the activity also dont handle the onTounEvent or OnClick(whole layout).

setError popup not repositioning correctly after hitting back on soft keyboard?

1) make 2 Edit Text fields close to the bottom of the screen, also a submit button (on submit have a setError called on the first field)
2) run the app, enter some text in both fields, hit submit
3) you should see the error popup in the correct position (as expected), click into the 2nd text field, then click back into the first text field, the error popup is off-position (it's either not aligned correctly or the arrow is flipped in the wrong direction). While the soft keyboard is up in this case you can also hit back to close the soft keyboard but the error popup is still off-positioned.
Add this class to your source folder.
public class ListenerEditText extends EditText {
private KeyImeChange keyImeChangeListener;
public ListenerEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setKeyImeChangeListener(KeyImeChange listener){
keyImeChangeListener = listener;
}
public interface KeyImeChange {
public void onKeyIme(int keyCode, KeyEvent event);
}
#Override
public boolean onKeyPreIme (int keyCode, KeyEvent event){
if(keyImeChangeListener != null){
keyImeChangeListener.onKeyIme(keyCode, event);
}
return false;
}
}
In your XML file.
<com.src.ListenerEditText
android:id="#+id/password"
style="#style/EditBoxStyle"
android:ems="30"
android:hint="*API Key"
android:inputType="text|textNoSuggestions"
android:maxLength="250"
android:singleLine="true"
</com.src.ListenerEditText>
Add action for edittext.
password.setKeyImeChangeListener(new KeyImeChange() {
#Override
public void onKeyIme(int keyCode, KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
password.clearFocus();
}
}
});

when i click on "DONE" button on softkeybord how to go next activity android

when i click on softkeyboard my keyboard getdown or hide but i want to go to next activity when i click on "done " button on keyboard of android.so how to do it?
and my next qus is if i have 2 edit box in my layout when i click on first edit box then in my soft keyboard "next " would appear for going to next text box and when i go to second text box it change to "done".
thanks in advance....
x
Its is better to add some button in the layout as all android phones dont provide a consistent behaviour when using imeoptions.
This seems to be a bug. Different manufacturers make a customized keyboard for their phone which may not completely behave as the android standard keyboard. This issue has been raised before. Most people overcome this issue by either overiding the onKey event or using a TextWatcher class. A bug has been filed about this
http://code.google.com/p/android/issues/detail?id=2882
You can use a listener to check for imeoptions
incomeInput.setOnEditorActionListener(new EditText.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE){
//Do your stuff here
return true; // mark the event as consumed
}
return false;
}
}
You need to implement OnEditorActionListener interface.
Code looks like :
public class Main extends Activity implements OnEditorActionListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main1);
}
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
startActivity(new Intent());
return true;
}
return false;
}}
Use setOnKeyListener with your second EditText and in onKey method do something like this.
#Override
public boolean onKey(View v, int keyCode, KeyEvent event)
{
// TODO Auto-generated method stub
if(keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN)
performYourAction();
return false;
}
I hope it will be helpfull for you.

Android - Handle "Enter" in an EditText

I am wondering if there is a way to handle the user pressing Enter while typing in an EditText, something like the onSubmit HTML event.
Also wondering if there is a way to manipulate the virtual keyboard in such a way that the "Done" button is labeled something else (for example "Go") and performs a certain action when clicked (again, like onSubmit).
I am wondering if there is a way to
handle the user pressing Enter while
typing in an EditText, something like
the onSubmit HTML event.
Yes.
Also wondering if there is a way to
manipulate the virtual keyboard in
such a way that the "Done" button is
labeled something else (for example
"Go") and performs a certain action
when clicked (again, like onSubmit).
Also yes.
You will want to look at the android:imeActionId and android:imeOptions attributes, plus the setOnEditorActionListener() method, all on TextView.
For changing the text of the "Done" button to a custom string, use:
mEditText.setImeActionLabel("Custom text", KeyEvent.KEYCODE_ENTER);
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
Toast.makeText(HelloFormStuff.this, edittext.getText(), Toast.LENGTH_SHORT).show();
return true;
}
return false;
}
});
Here's what you do. It's also hidden in the Android Developer's sample code 'Bluetooth Chat'. Replace the bold parts that say "example" with your own variables and methods.
First, import what you need into the main Activity where you want the return button to do something special:
import android.view.inputmethod.EditorInfo;
import android.widget.TextView;
import android.view.KeyEvent;
Now, make a variable of type TextView.OnEditorActionListener for your return key (here I use exampleListener);
TextView.OnEditorActionListener exampleListener = new TextView.OnEditorActionListener(){
Then you need to tell the listener two things about what to do when the return button is pressed. It needs to know what EditText we're talking about (here I use exampleView), and then it needs to know what to do when the Enter key is pressed (here, example_confirm()). If this is the last or only EditText in your Activity, it should do the same thing as the onClick method for your Submit (or OK, Confirm, Send, Save, etc) button.
public boolean onEditorAction(TextView exampleView, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_NULL
&& event.getAction() == KeyEvent.ACTION_DOWN) {
example_confirm();//match this behavior to your 'Send' (or Confirm) button
}
return true;
}
Finally, set the listener (most likely in your onCreate method);
exampleView.setOnEditorActionListener(exampleListener);
This page describes exactly how to do this.
https://developer.android.com/training/keyboard-input/style.html
Set the android:imeOptions then you just check the actionId in onEditorAction. So if you set imeOptions to 'actionDone' then you would check for 'actionId == EditorInfo.IME_ACTION_DONE' in onEditorAction. Also, make sure to set the android:inputType.
If using Material Design put code in TextInputEditText.
Here's the EditText from the example linked above:
<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 also set this programmatically using the setImeOptions(int) function. Here's the OnEditorActionListener from the example linked above:
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;
}
});
Hardware keyboards always yield enter events, but software keyboards return different actionIDs and nulls in singleLine EditTexts. This code responds every time the user presses enter in an EditText that this listener has been set to, regardless of EditText or keyboard type.
import android.view.inputmethod.EditorInfo;
import android.view.KeyEvent;
import android.widget.TextView.OnEditorActionListener;
listener=new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView view, int actionId, KeyEvent event) {
if (event==null) {
if (actionId==EditorInfo.IME_ACTION_DONE);
// Capture soft enters in a singleLine EditText that is the last EditText.
else if (actionId==EditorInfo.IME_ACTION_NEXT);
// Capture soft enters in other singleLine EditTexts
else return false; // Let system handle all other null KeyEvents
}
else if (actionId==EditorInfo.IME_NULL) {
// Capture most soft enters in multi-line EditTexts and all hard enters.
// They supply a zero actionId and a valid KeyEvent rather than
// a non-zero actionId and a null event like the previous cases.
if (event.getAction()==KeyEvent.ACTION_DOWN);
// We capture the event when key is first pressed.
else return true; // We consume the event when the key is released.
}
else return false;
// We let the system handle it when the listener
// is triggered by something that wasn't an enter.
// Code from this point on will execute whenever the user
// presses enter in an attached view, regardless of position,
// keyboard, or singleLine status.
if (view==multiLineEditText) multiLineEditText.setText("You pressed enter");
if (view==singleLineEditText) singleLineEditText.setText("You pressed next");
if (view==lastSingleLineEditText) lastSingleLineEditText.setText("You pressed done");
return true; // Consume the event
}
};
The default appearance of the enter key in singleLine=false gives a bent arrow enter keypad. When singleLine=true in the last EditText the key says DONE, and on the EditTexts before it it says NEXT. By default, this behavior is consistent across all vanilla, android, and google emulators. The scrollHorizontal attribute doesn't make any difference. The null test is important because the response of phones to soft enters is left to the manufacturer and even in the emulators, the vanilla Level 16 emulators respond to long soft enters in multi-line and scrollHorizontal EditTexts with an actionId of NEXT and a null for the event.
I know this is a year old, but I just discovered this works perfectly for an EditText.
EditText textin = (EditText) findViewById(R.id.editText1);
textin.setInputType(InputType.TYPE_CLASS_TEXT);
It prevents anything but text and space. I could not tab, "return" ("\n"), or anything.
In your xml, add the imeOptions attribute to the editText
<EditText
android:id="#+id/edittext_additem"
...
android:imeOptions="actionDone"
/>
Then, in your Java code, add the OnEditorActionListener to the same EditText
mAddItemEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if(actionId == EditorInfo.IME_ACTION_DONE){
//do stuff
return true;
}
return false;
}
});
Here is the explanation-
The imeOptions=actionDone will assign "actionDone" to the EnterKey. The EnterKey in the keyboard will change from "Enter" to "Done". So when Enter Key is pressed, it will trigger this action and thus you will handle it.
I had a similar purpose. I wanted to resolve pressing the "Enter" key on the keyboard (which I wanted to customize) in an AutoCompleteTextView which extends TextView. I tried different solutions from above and they seemed to work. BUT I experienced some problems when I switched the input type on my device (Nexus 4 with AOKP ROM) from SwiftKey 3 (where it worked perfectly) to the standard Android keyboard (where instead of handling my code from the listener, a new line was entered after pressing the "Enter" key. It took me a while to handle this problem, but I don't know if it will work under all circumstances no matter which input type you use.
So here's my solution:
Set the input type attribute of the TextView in the xml to "text":
android:inputType="text"
Customize the label of the "Enter" key on the keyboard:
myTextView.setImeActionLabel("Custom text", KeyEvent.KEYCODE_ENTER);
Set an OnEditorActionListener to the TextView:
myTextView.setOnEditorActionListener(new OnEditorActionListener()
{
#Override
public boolean onEditorAction(TextView v, int actionId,
KeyEvent event)
{
boolean handled = false;
if (event.getAction() == KeyEvent.KEYCODE_ENTER)
{
// Handle pressing "Enter" key here
handled = true;
}
return handled;
}
});
I hope this can help others to avoid the problems I had, because they almost drove me nuts.
Just as an addendum to Chad's response (which worked almost perfectly for me), I found that I needed to add a check on the KeyEvent action type to prevent my code executing twice (once on the key-up and once on the key-down event).
if (actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_DOWN)
{
// your code here
}
See http://developer.android.com/reference/android/view/KeyEvent.html for info about repeating action events (holding the enter key) etc.
You can also do it..
editText.setOnKeyListener(new OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event)
{
if (event.getAction() == KeyEvent.ACTION_DOWN
&& event.getKeyCode() == KeyEvent.KEYCODE_ENTER)
{
Log.i("event", "captured");
return false;
}
return false;
}
});
If you use DataBinding, see https://stackoverflow.com/a/52902266/2914140 and https://stackoverflow.com/a/67933283/2914140.
Bindings.kt:
#BindingAdapter("onEditorEnterAction")
fun EditText.onEditorEnterAction(callback: OnActionListener?) {
if (callback == null) setOnEditorActionListener(null)
else setOnEditorActionListener { v, actionId, event ->
val imeAction = when (actionId) {
EditorInfo.IME_ACTION_DONE,
EditorInfo.IME_ACTION_SEND,
EditorInfo.IME_ACTION_GO -> true
else -> false
}
val keydownEvent = event?.keyCode == KeyEvent.KEYCODE_ENTER
&& event.action == KeyEvent.ACTION_DOWN
if (imeAction or keydownEvent) {
callback.enterPressed()
return#setOnEditorActionListener true
}
return#setOnEditorActionListener false
}
}
interface OnActionListener {
fun enterPressed()
}
layout.xml:
<data>
<variable
name="viewModel"
type="YourViewModel" />
</data>
<EditText
android:imeOptions="actionDone|actionSend|actionGo"
android:singleLine="true"
android:text="#={viewModel.message}"
app:onEditorEnterAction="#{() -> viewModel.send()}" />
First, you have to set EditText listen to key press
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Set the EditText listens to key press
EditText edittextproductnumber = (EditText) findViewById(R.id.editTextproductnumber);
edittextproductnumber.setOnKeyListener(this);
}
Second, define the event upon the key press, for example, event to set TextView's text:
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
// Listen to "Enter" key press
if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER))
{
TextView textviewmessage = (TextView) findViewById(R.id.textViewmessage);
textviewmessage.setText("You hit 'Enter' key");
return true;
}
return false;
}
And finally, do not forget to import EditText,TextView,OnKeyListener,KeyEvent at top:
import android.view.KeyEvent;
import android.view.View.OnKeyListener;
import android.widget.EditText;
import android.widget.TextView;
password.setOnEditorActionListener(new TextView.OnEditorActionListener() {
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if(event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);
submit.performClick();
return true;
}
return false;
}
});
Works very fine for me
In addition hide keyboard
working perfectly
public class MainActivity extends AppCompatActivity {
TextView t;
Button b;
EditText e;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
b = (Button) findViewById(R.id.b);
e = (EditText) findViewById(R.id.e);
e.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (before == 0 && count == 1 && s.charAt(start) == '\n') {
b.performClick();
e.getText().replace(start, start + 1, ""); //remove the <enter>
}
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
#Override
public void afterTextChanged(Editable s) {}
});
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
b.setText("ok");
}
});
}
}
working perfectly
editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId != 0 || event.getAction() == KeyEvent.ACTION_DOWN) {
// Action
return true;
} else {
return false;
}
}
});
Xml
<EditText
android:id="#+id/editText2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="#string/password"
android:imeOptions="actionGo|flagNoFullscreen"
android:inputType="textPassword"
android:maxLines="1" />
This should work
input.addTextChangedListener(new TextWatcher() {
#Override
public void afterTextChanged(Editable s) {}
#Override
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start,
int before, int count) {
if( -1 != input.getText().toString().indexOf( "\n" ) ){
input.setText("Enter was pressed!");
}
}
});
Type this code in your editor so that it can import necessary modules.
query.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) {
if(actionId == EditorInfo.IME_ACTION_DONE
|| keyEvent.getAction() == KeyEvent.ACTION_DOWN
|| keyEvent.getAction() == KeyEvent.KEYCODE_ENTER) {
// Put your function here ---!
return true;
}
return false;
}
});
you can use this way
editText.setOnEditorActionListener((v, actionId, event) -> {
if (actionId == EditorInfo.IME_ACTION_DONE) {
// Do some things
return true;
}
return false;
});
you can see list of action there.
For example:
IME_ACTION_GO
IME_ACTION_SEARCH
IME_ACTION_SEND
This works fine on LG Android phones. It prevents ENTER and other special characters to be interpreted as normal character. Next or Done button appears automatically and ENTER works as expected.
edit.setInputType(InputType.TYPE_CLASS_TEXT);
Here's a simple static function that you can throw into your Utils or Keyboards class that will execute code when the user hits the return key on a hardware or software keyboard. It's a modified version of #earlcasper's excellent answer
/**
* Return a TextView.OnEditorActionListener that will execute code when an enter is pressed on
* the keyboard.<br>
* <code>
* myTextView.setOnEditorActionListener(Keyboards.onEnterEditorActionListener(new Runnable()->{
* Toast.makeText(context,"Enter Pressed",Toast.LENGTH_SHORT).show();
* }));
* </code>
* #param doOnEnter A Runnable for what to do when the user hits enter
* #return the TextView.OnEditorActionListener
*/
public static TextView.OnEditorActionListener onEnterEditorActionListener(final Runnable doOnEnter){
return (__, actionId, event) -> {
if (event==null) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
// Capture soft enters in a singleLine EditText that is the last EditText.
doOnEnter.run();
return true;
} else if (actionId==EditorInfo.IME_ACTION_NEXT) {
// Capture soft enters in other singleLine EditTexts
doOnEnter.run();
return true;
} else {
return false; // Let system handle all other null KeyEvents
}
} else if (actionId==EditorInfo.IME_NULL) {
// Capture most soft enters in multi-line EditTexts and all hard enters.
// They supply a zero actionId and a valid KeyEvent rather than
// a non-zero actionId and a null event like the previous cases.
if (event.getAction()==KeyEvent.ACTION_DOWN) {
// We capture the event when key is first pressed.
return true;
} else {
doOnEnter.run();
return true; // We consume the event when the key is released.
}
} else {
// We let the system handle it when the listener
// is triggered by something that wasn't an enter.
return false;
}
};
}
InputType on the textfield must be text in order for what CommonsWare said to work. Just tried all of this, no inputType before the trial and nothing worked, Enter kept registering as soft enter. After inputType = text, everything including the setImeLabel worked.
Example : android:inputType="text"
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
Toast.makeText(HelloFormStuff.this, edittext.getText(), Toast.LENGTH_SHORT).show();
return true;
}
return false;
}
});
Using Kotlin I've made a function that handles all kinds of "done"-like actions for EditText, including the keyboard, and it's possible to modify it and also handle other keys as you wish, too :
private val DEFAULT_ACTIONS_TO_HANDLE_AS_DONE_FOR_EDIT_TEXT = arrayListOf(EditorInfo.IME_ACTION_SEND, EditorInfo.IME_ACTION_GO, EditorInfo.IME_ACTION_SEARCH, EditorInfo.IME_ACTION_DONE)
private val DEFAULT_KEYS_TO_HANDLE_AS_DONE_FOR_EDIT_TEXT = arrayListOf(KeyEvent.KEYCODE_ENTER, KeyEvent.KEYCODE_NUMPAD_ENTER)
fun EditText.setOnDoneListener(function: () -> Unit, onKeyListener: OnKeyListener? = null, onEditorActionListener: TextView.OnEditorActionListener? = null,
actionsToHandle: Collection<Int> = DEFAULT_ACTIONS_TO_HANDLE_AS_DONE_FOR_EDIT_TEXT,
keysToHandle: Collection<Int> = DEFAULT_KEYS_TO_HANDLE_AS_DONE_FOR_EDIT_TEXT) {
setOnEditorActionListener { v, actionId, event ->
if (onEditorActionListener?.onEditorAction(v, actionId, event) == true)
return#setOnEditorActionListener true
if (actionsToHandle.contains(actionId)) {
function.invoke()
return#setOnEditorActionListener true
}
return#setOnEditorActionListener false
}
setOnKeyListener { v, keyCode, event ->
if (onKeyListener?.onKey(v, keyCode, event) == true)
return#setOnKeyListener true
if (event.action == KeyEvent.ACTION_DOWN && keysToHandle.contains(keyCode)) {
function.invoke()
return#setOnKeyListener true
}
return#setOnKeyListener false
}
}
So, sample usage:
editText.setOnDoneListener({
//do something
})
As for changing the label, I think it depends on the keyboard app, and that it usually change only on landscape, as written here. Anyway, example usage for this:
editText.imeOptions = EditorInfo.IME_ACTION_DONE
editText.setImeActionLabel("ASD", editText.imeOptions)
Or, if you want in XML:
<EditText
android:id="#+id/editText" android:layout_width="wrap_content" android:layout_height="wrap_content"
android:imeActionLabel="ZZZ" android:imeOptions="actionDone" />
And the result (shown in landscape) :
Kotlin solution to react to enter press using Lambda expression:
editText.setOnKeyListener { _, keyCode, event ->
if(keyCode == KeyEvent.KEYCODE_ENTER && event.action==KeyEvent.ACTION_DOWN){
//react to enter press here
}
true
}
not doing the additional check for the type of event will cause this listener to be called twice when pressed once (once for ACTION_DOWN, once for ACTION_UP)
A dependable way to respond to an <enter> in an EditText is with a TextWatcher, a LocalBroadcastManager, and a BroadcastReceiver. You need to add the v4 support library to use the LocalBroadcastManager. I use the tutorial at vogella.com: 7.3 "Local broadcast events with LocalBroadcastManager" because of its complete concise code Example. In onTextChanged before is the index of the end of the change before the change>;minus start. When in the TextWatcher the UI thread is busy updating editText's editable, so we send an Intent to wake up the BroadcastReceiver when the UI thread is done updating editText.
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.text.Editable;
//in onCreate:
editText.addTextChangedListener(new TextWatcher() {
public void onTextChanged
(CharSequence s, int start, int before, int count) {
//check if exactly one char was added and it was an <enter>
if (before==0 && count==1 && s.charAt(start)=='\n') {
Intent intent=new Intent("enter")
Integer startInteger=new Integer(start);
intent.putExtra("Start", startInteger.toString()); // Add data
mySendBroadcast(intent);
//in the BroadcastReceiver's onReceive:
int start=Integer.parseInt(intent.getStringExtra("Start"));
editText.getText().replace(start, start+1,""); //remove the <enter>
//respond to the <enter> here
This question hasn't been answered yet with Butterknife
LAYOUT XML
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/some_input_hint">
<android.support.design.widget.TextInputEditText
android:id="#+id/textinput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:imeOptions="actionSend"
android:inputType="text|textCapSentences|textAutoComplete|textAutoCorrect"/>
</android.support.design.widget.TextInputLayout>
JAVA APP
#OnEditorAction(R.id.textinput)
boolean onEditorAction(int actionId, KeyEvent key){
boolean handled = false;
if (actionId == EditorInfo.IME_ACTION_SEND || (key.getKeyCode() == KeyEvent.KEYCODE_ENTER)) {
//do whatever you want
handled = true;
}
return handled;
}
Replace "txtid" with your EditText ID.
EditText txtinput;
txtinput=findViewById(R.id.txtid)
txtinput.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) || (actionId == EditorInfo.IME_ACTION_DONE)) {
//Code for the action you want to proceed with.
InputMethodManager inputManager = (InputMethodManager)
getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
}
return false;
}
});
Add these depencendy, and it should work:
import android.view.KeyEvent;
import android.view.View;
import android.widget.EditText;
This will give you a callable function when the user presses the return key.
fun EditText.setLineBreakListener(onLineBreak: () -> Unit) {
val lineBreak = "\n"
doOnTextChanged { text, _, _, _ ->
val currentText = text.toString()
// Check if text contains a line break
if (currentText.contains(lineBreak)) {
// Uncommenting the lines below will remove the line break from the string
// and set the cursor back to the end of the line
// val cleanedString = currentText.replace(lineBreak, "")
// setText(cleanedString)
// setSelection(cleanedString.length)
onLineBreak()
}
}
}
Usage
editText.setLineBreakListener {
doSomething()
}
I created a helper class for this by extending the new MaterialAlertDialogBuilder
Usage
new InputPopupBuilder(context)
.setInput(R.string.send,
R.string.enter_your_message,
text -> sendFeedback(text, activity))
.setTitle(R.string.contact_us)
.show();
Code
public class InputPopupBuilder extends MaterialAlertDialogBuilder {
private final Context context;
private final AppCompatEditText input;
public InputPopupBuilder(Context context) {
super(context);
this.context = context;
input = new AppCompatEditText(context);
input.setInputType(InputType.TYPE_CLASS_TEXT);
setView(input);
}
public InputPopupBuilder setInput(int actionLabel, int hint, Callback callback) {
input.setHint(hint);
input.setImeActionLabel(context.getString(actionLabel), KeyEvent.KEYCODE_ENTER);
input.setOnEditorActionListener((TextView.OnEditorActionListener) (v, actionId, event) -> {
if (actionId == EditorInfo.IME_NULL
&& event.getAction() == KeyEvent.ACTION_DOWN) {
Editable text = input.getText();
if (text != null) {
callback.onClick(text.toString());
return true;
}
}
return false;
});
setPositiveButton(actionLabel, (dialog, which) -> {
Editable text = input.getText();
if (text != null) {
callback.onClick(text.toString());
}
});
return this;
}
public InputPopupBuilder setText(String text){
input.setText(text);
return this;
}
public InputPopupBuilder setInputType(int inputType){
input.setInputType(inputType);
return this;
}
public interface Callback {
void onClick(String text);
}
}
Requires
implementation 'com.google.android.material:material:1.3.0-alpha04'

Categories

Resources