Android imeOptions="actionDone" not working

57.9k views Asked by At

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.

9

There are 9 answers

1
Oat Anirut On BEST ANSWER

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

0
Qianqian On

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

1
peedee On

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.

0
Ashfaque On

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;
});
0
Harsha Sharma On

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

1
Ali Alp On

just Add this to your attributes :

android:inputType="textPassword"

Doc: here

0
PouleyKetchoupp On

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;
}
1
Jeremy Freeley On

After trying many things, this is what worked for me:

    android:maxLines="1"
    android:inputType="text"
    android:imeOptions="actionDone"
1
Mani On

Use android:inputType="Yours" then

android:lines="1"
android:imeOptions="actionDone"