Android imeOptions="actionDone" not working - android

I am trying to get a login screen for an Android app and so far this is my code:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="vertical">
<EditText
android:id="#+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Username"
android:inputType="text"
android:singleLine="true"
android:imeOptions="actionNext">
<requestFocus />
</EditText>
<EditText
android:id="#+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Password"
android:inputType="textPassword"
android:singleLine="true"
android:imeOptions="actionDone" />
<Button
android:id="#+id/buttonLaunchTriage"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="#string/login" />
</LinearLayout>
</RelativeLayout>
When I try to run it, the keyboard shows the right keys but when I try to press done after entering the password, nothing happens. I am using this to handle the button press:
private void setupLoginButton() {
Button launchButton = (Button) findViewById(R.id.buttonLaunchTriage);
launchButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
EditText username = (EditText) findViewById(R.id.patient_start_userName_value);
EditText password = (EditText) findViewById(R.id.patient_start_password_value);
try {
if(TriageApplicationMain.validateUser(username.getText().toString(),password.getText().toString(),getApplicationContext()))
{
Toast.makeText(StartActivity.this,
"Launching Triage Application", Toast.LENGTH_SHORT)
.show();
startActivity(new Intent(StartActivity.this, MainActivity.class));
}
else
{
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
StartActivity.this);
// set dialog message
alertDialogBuilder
.setMessage("Incorrect Credentials")
.setCancelable(false)
.setPositiveButton("OK",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id) {
// if this button is clicked, close
// current activity
dialog.cancel();
}
});
// create alert dialog
AlertDialog alertDialog = alertDialogBuilder.create();
// show it
alertDialog.show();
}
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
I know this is a lot of code, but if anyone could help me here it would be great. This is for a school project.
PS: I have searched through Google for a solid hour before posting this so please don't criticize for not doing that. If you find a link that is useful then please share.

Just add android:inputType="..." to your EditText. It will work!! :)

You should set OnEditorActionListener for the EditText to implement the action you want to perform when user clicks the "Done" in keyboard.
Thus, you need to write some code like:
password.setOnEditorActionListener(new OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
// Do whatever you want here
return true;
}
return false;
}
});
See the tutorial at android developer site

Qianqian is correct. Your code only listens for the button click event, not for the EditorAction event.
I want to add that some phone vendors may not properly implement the DONE action. I have tested this with a Lenovo A889 for example, and that phone never sends EditorInfo.IME_ACTION_DONEwhen you press done, it always sends EditorInfo.IME_ACTION_UNSPECIFIED so I actually end up with something like
myEditText.setOnEditorActionListener(new EditText.OnEditorActionListener() {
#Override
public boolean onEditorAction(final TextView v, final int actionId, final KeyEvent event)
{
boolean handled=false;
// Some phones disregard the IME setting option in the xml, instead
// they send IME_ACTION_UNSPECIFIED so we need to catch that
if(EditorInfo.IME_ACTION_DONE==actionId || EditorInfo.IME_ACTION_UNSPECIFIED==actionId)
{
// do things here
handled=true;
}
return handled;
}
});
Also note the "handled" flag (Qianqian didn't explain that part). It might be that other OnEditorActionListeners higher up are listening for events of a different type. If your method returns false, that means you didn't handle this event and it will be passed on to others. If you return true that means you handled/consumed it and it will not be passed on to others.

Use android:inputType="Yours" then
android:lines="1"
android:imeOptions="actionDone"

After trying many things, this is what worked for me:
android:maxLines="1"
android:inputType="text"
android:imeOptions="actionDone"

just Add this to your attributes :
android:inputType="textPassword"
Doc: here

You should set OnEditorActionListener for the EditText to implement the action you want to perform when user clicks the "Done" in keyboard.

Just to add to Qianqian & peedee answers:
Here's the reason why the action id is EditorInfo.IME_ACTION_UNSPECIFIED (0) for any enter event.
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.
(Source: Android documentation)
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;
}

in XML
android:id="#+id/edittext"
android:maxLines="1"
android:inputType="text"
android:imeOptions="actionDone"
in Java
edittext.setOnEditorActionListener((textView, actionId, keyEvent) - > {
if (actionId == EditorInfo.IME_ACTION_DONE) {
/////////////Your Code Here////////////////
return true;
}
return false;
});

Related

EditText OnKeyListener with setFocus not working as per expected

I am using an Android device with physical hardware keyboard.
I have two EditTexts (Part No and Qty) and Two Buttons (Reset and Save) on screen.
After user key in Qty, they want to press Enter key from physical keyboard to trigger "Save" function.
My current Save function will save the data to file and clear the data on screen and set the focus to Part No.
It seems like my onKeyListener didn't return True once it was consumed and it trigger another Enter key action to move my cursor to Qty field (by right, it should stay in Part No field).
I thought return True will indicate this Enter key has been consumed, am I understanding correct?
My two EditText are put directly under ConstraintLayout (not under any sub-layout).
Any idea on where my code goes wrong?
Below is my piece of code for layout.
<EditText
android:id="#+id/etPart"
android:layout_width="200dp"
android:maxLength="20"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:maxLines="1"
android:inputType="text"
android:imeOptions="actionNext"
app:layout_constraintLeft_toRightOf="#+id/tvPart"
app:layout_constraintTop_toTopOf="parent"/>
<EditText
android:id="#+id/etQty"
android:layout_width="100dp"
android:maxLength="5"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:inputType="number"
android:maxLines="1"
android:imeOptions="actionDone"
app:layout_constraintLeft_toRightOf="#+id/tvQty"
app:layout_constraintTop_toBottomOf="#id/etPart"
android:nextFocusDown="#id/etPart"/>
Below is my Java code.
This is in onCreate method.
etQty.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View view, int i, KeyEvent keyEvent) {
if(i == KeyEvent.KEYCODE_ENTER){
saveData(null);
// I tried to use return true here, sames result, no different.
}
return false;
}
});
This is the functions.
public void saveData(View view) {
// check and save data to file logic.
// ...... etc.
mProductViewModel.insert(product);
resetView(null);
}
public void resetView(View view) {
etPart.setText(null);
etQty.setText(null);
// I am expecting the focus will stay in Part No box but it is not. It will jump to Qty field.
etPart.requestFocus();
}
After checking with the specialist, I came to understand that I also need to handle Action Up (Key Up) too.
Below is the working code.
etQty.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View view, int i, KeyEvent keyEvent) {
if(i == KeyEvent.KEYCODE_ENTER && keyEvent.getAction() == KeyEvent.ACTION_UP){
saveData(null);
return true;
}
return false;
}
});
This is usually caused by soft keyboard, can you try this code?
etPart.requestFocus();
final InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.restartInput(etPart);
imm.showSoftInput(etPart, 0);

setOnEditorActionListener not working with soft keyboard submit button, but does with laptop Enter key?

Can someone please provide a solution to get a working listener for the soft-keyboard DONE button, and/or explain what I'm doing wrong in my current approach?
My Xml & Java Setup
In Xml, there's a simple EditText is set with android:imeOptions="actionDone"
In Java, it just has a basic TextView.OnEditorActionListener declared
So setOnEditorActionListener() is not getting called when there is a click from device soft-keyboard submit (aka DONE) button - the green arrow button below ; only the EditText field is cleared
But that listener DOES get called when clicking the computer Enter key (attached via ADB).
I would figure it should work for both those buttons .. is this not right?
XML Layout File:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.demo.MainActivity">
<EditText
android:id="#+id/comment_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:maxLines="1"
android:imeOptions="actionDone"
/>
</LinearLayout>
Java Activity File:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
((EditText) findViewById(R.id.comment_text)).setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
int i = 5; // added this to set a break point
return false;
}
});
}
}
Update for Solution
Thanks to #Apoorv Mehrotra's answer, it turns out that my EditText was missing this one attribute in order for the soft keyboard event to be recognized. Adding this to the above Xml solves the problem.
android:inputType="text"
I had the same problem, for me, adding android:singleLine="true" in EditText did the trick
try this code this is a code with 2 fields in which i have user time feature. in first one keyboard shows next button and in second one soft keypad shows done option and on done option i hide the soft keypad.
below is the xml file code.
<EditText
android:id="#+id/txt1"
android:layout_width="match_parent"
android:layout_height="100dp"
android:gravity="top|left"
android:imeOptions="actionNext"
android:inputType="text|textNoSuggestions"
android:text=""
android:visibility="visible" />
<EditText
android:id="#+id/txt2"
android:layout_width="match_parent"
android:layout_height="100dp"
android:gravity="top|left"
android:imeOptions="actionDone"
android:inputType="text|textNoSuggestions"
android:text=""
android:visibility="visible"
/>
now below is the java code: for hiding soft keypad on next and same can be performed for done option as well.
this code add in onCreate() of your class.
EditText first_txt = (EditText) findViewById(R.id.txt1);
EditText second_txt = (EditText) findViewById(R.id.txt2);
first_txt.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_NEXT) {
InputMethodManager imm = (InputMethodManager) getApplicationContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
return true; // Focus will do whatever you put in the logic.
}
return false; // Focus will change according to the actionId
}
});
second_txt.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
InputMethodManager imm = (InputMethodManager) getApplicationContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
return true; // Focus will do whatever you put in the logic.
}
return false; // Focus will change according to the actionId
}
});
This code works for , hope it helps you out!
This is an old issue that seems not to be solved yet. There's a workaround for these cases. Simply take the EditText (or whatever View you might be needing this and assign it a onEditorActionListener, like this:
final EditText editor = (EditText) findViewById(R.id.myEditText);
editor.setOnEditorActionListener(EnterOnText);
Now define the EnterOnText implementation like this:
TextView.OnEditorActionListener EnterOnText = new TextView.OnEditorActionListener() {
public boolean onEditorAction(TextView view, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_GO) {
final String msg = view.getText().toString();
if (!msg.isEmpty()) {
// Do whatever you need here
...
}
}
return true;
}
};
Now, simply change the layout's imeOptions attribute to:
android:imeOptions="actionGo"
That will, oppositely, probably make your emulator's enter key not work, but will (should) do on all physical devices.
((EditText) findViewById(R.id.comment_text)).setOnEditorActionListener(new OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if(actionId==EditorInfo.IME_ACTION_DONE){
//do something
}
return false;
}
});
Try this,
((EditText) findViewById(R.id.comment_text)).setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (event != null && (actionId == EditorInfo.IME_ACTION_GO
|| event.getKeyCode() == event.KEYCODE_ENTER))
{
//do whatever you want
}
}
});
<EditText
android:id="#+id/comment_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:maxLines="1"
android:imeOptions="actionGo"
/>

Press Enter to change EditText

My problem is that I have a login screen that contains 2 EditText views. When I enter the username and click Enter, it adds more lines, but I want it to change to the EditText password instead. Can someone please help me?
public void onClick(View v){
final TextView user = (TextView)findViewById(R.id.tnome);
final TextView pw = (TextView)findViewById(R.id.tpw);
if (user.getText().toString().equals("") || pw.getText().toString().equals((""))) {
Toast.makeText(MainActivity.this, "Têm de Preencher todos os Campos", Toast.LENGTH_SHORT).show();
user.requestFocus();
}else{
if (user.getText().toString().endsWith(" ")){
user.setText(user.getText().toString().substring(0,user.length()-1));
}
user.setText(user.getText().toString().toLowerCase());
if (user.getText().toString().equals("admin") && pw.getText().toString().equals("admin")){
startActivity(new Intent(MainActivity.this,Home.class));
user.setText("");
pw.setText("");
}
user.setOnKeyListener(new View.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
user.clearFocus();
pw.requestFocus();
return true;
}
return false;
}
});
pw.setOnKeyListener(new View.OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
if ((event.getAction() == KeyEvent.ACTION_DOWN) &&
(keyCode == KeyEvent.KEYCODE_ENTER))
{
// Perform action on Enter key press
// check for username - password correctness here
return true;
}
return false;
}
});
}
}
Using the android:inputType="text" (or another value) to limit input text to one line.
Usually, when input controls are laid out in a layout file (resx), pressing ENTER will cause focus to go to the next field. You shouldn't need any custom handling code to have this work (i.e. you shouldn't need code on the username field to make ENTER set focus to the password field).
You can use the <requestFocus /> tag to force focus to a field when the page is loaded.
<EditText
android:id="#+id/etUserName"
android:layout_margin="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textCapWords"
android:focusable="true"
>
<requestFocus />
</EditText>
<EditText
android:id="#+id/etPassword"
android:layout_margin="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:cursorVisible="true"
android:hint="Password"
/>
The most likely reason that the wire-up of the listener isn't working is that the code is only run when a button is clicked (it's in an onClick function). Perform the wire-up for the password (pw) field during page initialization instead - onFinishInflate() is a good spot.
You might, however want to wire-up a key listener to make an ENTER press in the password field submit the data (or do validation).

Not setOnKeyListener nor setOnEditorActionListener working unexpectedly

i am trying to do some thing when user press enter button in the EditText (It is multi lines editText means user can write more than one lines)
simply i want to detect either the enter key pressed
the code used is given below
<EditText
android:id="#+id/body"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/transparent"
android:hint="#string/hint"
android:padding="5dp"
android:scrollbars="vertical"
android:textColor="#android:color/black"
android:textCursorDrawable="#null"
android:textSize="22sp" />
and listener is
mBodyText.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View view, int i, KeyEvent keyEvent) {
if ((keyEvent.getAction()== KeyEvent.ACTION_UP)) {
if(i == KeyEvent.KEYCODE_ENTER){
Toast.makeText(getApplicationContext(), "neter presed", Toast.LENGTH_LONG).show();
return true;
}
}
return false;
}
});
but it do not show any thing when i press but show when i long press enter key
and setOnEditorActionListener is
mBodyText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) {
if ((keyEvent.getAction()== KeyEvent.ACTION_UP)) {
if(i == KeyEvent.KEYCODE_ENTER){
Toast.makeText(getApplicationContext(), "neter presed", Toast.LENGTH_LONG).show();
return true;
}
}
return false;
}
});
it shows nothing when i press enter key and application crashes when i long press the enter key
please help me i am trying it from long time
Disappointed no one there to Answer my question but i solved it on my own resources
setOnKeyListener was not working because the some of the android devices do not support this but most of them do support
and setOnEditorActionListener caused crashes because i am trying to get data from database and show it in my EditText view on the activity starts
thanks all especially #isma3l

have to click two times to call an onclick method of edittext android

I have this editText in my android activity
<EditText
android:id="#+id/payment_expiration"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/payment_expiration_label"
android:layout_centerHorizontal="true"
android:layout_marginLeft="25dp"
android:layout_marginRight="25dp"
android:clickable="true"
android:onClick="update_expiration_date"
android:editable="false"
android:layout_marginTop="-4dp"
android:cursorVisible="false"
android:maxLength="7"
android:padding="10dp"
android:textSize="13dp" />
as you can see when the user click on
I call this method which launch a datePickerDialog :
public void update_expiration_date(View v){
Log.i("","cliqué");
picker.show();
can_update_expiration_date = true;
}
the problem I encouter is : in the first time just when I open this activity, the user must click two times to launch the dialog
but after that, one click is sufficient
how can I fix this issue
Check Similar Question
"The first click just sets the focus to the TextBox then the second click actually gets handled as a click. "
try setting android:focusable="false"
You could try the focusable solution, or just add a state tracking variable...
public class YourActivity extends Activity {
private boolean clicked;
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
clicked = false;
}
public void update_expiration_date(View v){
if(clicked == false){
clicked = true;
return;
} else {
Log.i("","cliqué");
picker.show();
can_update_expiration_date = true;
}
}
}
begiPass solution works but there are a better.
With focusable false the user never can´t see which edittext is selected.
The better solution is using onTouchListener. My example code:
edit.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
edit.setText("");
v.setOnTouchListener(null);
return false;
}
});
Don´t forget set OnTouchListener to null. We want just clear the hint (only once time).
Regards!
Use OnTouchListener handle it:
when (view) {
edtName -> {
if (motionEvent.action == MotionEvent.ACTION_UP) {
edtName.requestFocus()
//TODO
}
}
edtPassword -> {
if (motionEvent.action == MotionEvent.ACTION_UP) {
edtPassword.requestFocus()
//TODO
}
}
}
return false
}```

Categories

Resources