Android imeOptions="actionDone" не работает

Я пытаюсь получить экран входа для приложения Android, и пока это мой код:

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

Когда я пытаюсь запустить его, клавиатура показывает правильные клавиши, но когда я пытаюсь нажать "Готово" после ввода пароля, ничего не происходит. Я использую это для обработки нажатия кнопки:

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();
            }
        }
    });

}

Я знаю, что это много кода, но если бы кто-нибудь мог мне здесь помочь, было бы здорово. Это для школьного проекта.

PS: я искал в Google целый час, прежде чем опубликовать это, поэтому, пожалуйста, не критикуйте за то, что вы этого не сделали. Если вы найдете ссылку, которая полезна, пожалуйста, поделитесь.

9 ответов

Решение

Вы должны установить OnEditorActionListener для EditText, чтобы реализовать действие, которое вы хотите выполнить, когда пользователь нажимает "Готово" на клавиатуре.

Таким образом, вам нужно написать такой код:

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;
    }
});

Смотрите руководство на сайте разработчиков Android

Просто добавь android:inputType="..." на ваш EditText. Это будет работать!!:)

Qianqian правильно. Ваш код прослушивает только событие нажатия кнопки, а не событие EditorAction.

Я хочу добавить, что некоторые поставщики телефонов могут неправильно реализовывать действие DONE. Я проверял это на Lenovo A889, например, и этот телефон никогда не отправляет EditorInfo.IME_ACTION_DONEкогда вы нажимаете готово, он всегда отправляет EditorInfo.IME_ACTION_UNSPECIFIED так что я на самом деле в конечном итоге с чем-то вроде

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;
  }
});

Также обратите внимание на флаг "обработано" (Qianqian не объяснил эту часть). Возможно, другие OnEditorActionListeners выше слушают события другого типа. Если ваш метод возвращает false, это означает, что вы не обработали это событие, и оно будет передано другим. Если вы вернете true, это означает, что вы обработали / потребили его, и он не будет передан другим.

Использование android:inputType="Yours" затем

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

Попробовав много вещей, вот что сработало для меня:

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

Просто добавьте это к вашим атрибутам:

android:inputType="textPassword"

Док: здесь

Вы должны установить OnEditorActionListener для EditText, чтобы реализовать действие, которое вы хотите выполнить, когда пользователь нажимает "Готово" на клавиатуре.

Просто чтобы добавить к ответам Qianqian & peedee:

Вот причина, по которой идентификатор действия равен EditorInfo.IME_ACTION_UNSPECIFIED (0) для любого события ввода.

actionId int: Идентификатор действия. Это будет либо указанный вами идентификатор, либо EditorInfo#IME_NULL, если вызывается из-за нажатия клавиши ввода.

(Источник: документация Android)

Таким образом, правильным способом обработки событий ввода ключа будет:

@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
    if (actionId == EditorInfo.IME_NULL) {
        // Handle return key here
        return true;
    }
    return false;
}

в XML

      android:id="@+id/edittext"
android:maxLines="1"
android:inputType="text"
android:imeOptions="actionDone"

на Яве

      edittext.setOnEditorActionListener((textView, actionId, keyEvent) - > {
    if (actionId == EditorInfo.IME_ACTION_DONE) {
        /////////////Your Code Here////////////////
        return true;
    }
    return false;
});
Другие вопросы по тегам