How to make edittext autofocus after showing a Toast? - android

I have a EditText that reads a 13 digit barcode. What I want to do is to keep the virtual keyboard shown on the screen and the EditText to always have focus. The following code let me write the barcode and search for a product when enter key is pressed, and it works well. But if I type a barcode with less then 13 digits or the barcode typed does not exist in my database, I want to show the user a Toast, informing him of it. After displaying the Toast, I want the EditText to gain focus again automatically, letting the user just type the barcode again. After showing the Toast, I tried the requestFocus() method, but it didn't work. The soft keyboard is always shown, but after the Toast, I can't type in the EditText again unless I touch on the EditText. How can I do this?
final EditText procura_codbar = (EditText)
findViewById(R.id.procurar_produto_codbar);
procura_codbar.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if ((event.getAction() == KeyEvent.ACTION_DOWN)
&& (keyCode == KeyEvent.KEYCODE_ENTER)) {
String codbar = procura_codbar.getText().toString();
if (codbar.length()<13){
Toast.makeText(MainActivity.this,
"type a 13 digit barcode",
Toast.LENGTH_LONG).show();
}
else{
if (bdh!=null){
bdh.closedb(); bdh.close();
}
bdh = new DBHelper(MainActivity.this);
Log.i("CODBAR", codbar);
produto prod_ = bdh.getProduto(codbar);
if (prod_!=null){
showDialogPreco(prod_);
procura_codbar.setText("");
}else{
Toast.makeText(MainActivity.this,
"Product not found",
Toast.LENGTH_SHORT).show();
procura_codbar.setSelection(codbar.length());
}
}
procura_codbar.requestFocus();
procura_codbar.setSelection(codbar.length());
}
return false;
}
});
And here is the XML:
<EditText
android:id="#+id/procurar_produto_codbar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:inputType="textNoSuggestions|number"
android:textSize="22sp"
android:maxLength="13"
android:layout_toRightOf="#+id/tv_procura_codbar" >
<requestFocus />
</EditText>
Thanks in advance.
EDIT: Messing with this, I found the problem. Heres the solution:
return true;
Now it works...

Put this code right next to that Toast Message:
Toast.makeText(MainActivity.this,
"type a 13 digit barcode",
Toast.LENGTH_LONG).show();
procura_codbar.setFocusableInTouchMode(true);
procura_codbar.setFocusable(true);
procura_codbar.requestFocus();
procura_codbar.setSelection(codbar.length());
This worked for me. Also you need to remove the *procura_codbar.requestFocus();* at the bottom of the code.

I've only been able to get the focus back to the EditText by delaying momentarily before calling the requestFocus() method:
final Handler handler = new Handler();
final EditText myEditText = (EditText) findViewById(R.id.editText1);
myEditText.setOnKeyListener(new OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
// See if user presses enter
if (event.getAction() == KeyEvent.ACTION_DOWN &&
keyCode == KeyEvent.KEYCODE_ENTER) {
Toast.makeText(MainActivity.this, "You pressed enter!",
Toast.LENGTH_SHORT).show();
// Put focus back in the EditText after brief delay
handler.postDelayed(new Runnable() {
#Override
public void run() {
myEditText.requestFocus();
// Select all text
myEditText.setSelection(0, myEditText.getText().length());
}
}, 200);
return true;
}
return false;
}
});

Related

How to type through the keyboard programmatically in android

When user click on the field and keyboard comes up, by pressing the Enter/Go key, I want to type my own value into the field, instead of system keyboard.
I want to do this in background of my app, and fill the fields of other apps.
Is it possible job, or I'm a greedy man?! :)
Yes it is possible, you are not greedy :P
You can add onKeyListener() on each of your EditText fields. It will listen to each key stroke by you user and as soon user press Enter, you can perform your required logic.
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)) {
Toast.makeText(MyExampleActivity.this, "enter is pressed", Toast.LENGTH_SHORT).show();
return true;
}
return false;
}
});

Only Error icon is visible while setting error to EditText in InputTextLayout

When user enter invalid email or mobile while registration, I am setting error to EditText.
Please check below code:
<android.support.design.widget.TextInputLayout
android:id="#+id/txt_input_mobile_number"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="#+id/input_mobile_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Mobile number"
android:maxLength="10"
android:inputType="number"
android:maxLines="1"/>
</android.support.design.widget.TextInputLayout>
MyFragment.java implements below OnKeyListener:
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if ((event.getAction() == KeyEvent.ACTION_DOWN) &&
(keyCode == KeyEvent.KEYCODE_ENTER)) {
// perform validation of data here
switch (v.getId()) {
case R.id.input_mobile_number:
EditText editMobile = (EditText)getActivity().findViewById(R.id.input_mobile_number);
Editable phone = binding.inputMobileNumber.getText();
if (phone != null && isValidMobile(phone.toString())) {
editMobile.setError("Please enter valid mobile number");
editMobile.requestFocus();
}
break;
}
return true;
}
return false;
}
Below screenshot displays, Only error icon is visible not error box like other one:
with only symbol
with error prompt
You should use TextInputLayout instead of EditText for your Requirement .
TextInputLayout tilObj = (TextInputLayout) findViewById(R.id.txt_input_mobile_number);
tilObj .setErrorEnabled(true);
tilObj .setError("Please enter valid mobile number");
Figured out!!
When we use TextInputLayout we need to set error not to EditText but TextInputLayout itself.
So I have changed my code as below:
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if ((event.getAction() == KeyEvent.ACTION_DOWN) &&
(keyCode == KeyEvent.KEYCODE_ENTER)) {
// perform validation of data here
switch (v.getId()) {
case R.id.input_mobile_number:
// check it is TextInputLayout not EditText
TextInputLayout editMobile = (EditText)getActivity().findViewById(R.id.txt_input_mobile_number);
Editable phone = binding.inputMobileNumber.getText();
if (phone != null && isValidMobile(phone.toString())) {
editMobile.setError("Please enter valid mobile number");
editMobile.requestFocus();
}
break;
}
return true;
}
return false;
}
Maybe the space between these two TextInputLayout is low and you cannot see the error message , try to put more margin between them.

Text watcher in android works once only

I have written a key listener on a edit text in android.
Following is my code:
textview.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 Enter key press
if (textview.getText().toString().length() == 15) {
textvalue = textview.getText().toString();
textview.setText(replacecardformat());
textview.clearFocus();
Log.e(""TAG, "Executed");
return true;
} else {
return false;
}
}
return false;
}
});
However the log statement is executed only once.Is some problem in my return statement.
Two observations:
if you need listener on each text change use view.addTextChangedListener(TextWatcher). Text Watcher has three methods: one fired before, one after, and one on text change. I suppose that this is what you are looking for. More details and tutorial you can find here
is your textview an TextView or EditText? I am asking since only EditText can receive keyboard input. however TextView can have such listener too. Because its text can also change (see documentation here).

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).

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