Android: показывать программную клавиатуру автоматически, когда фокус находится на EditText - PullRequest
318 голосов
/ 08 марта 2010

Я показываю поле ввода, используя AlertDialog. EditText внутри самого диалога автоматически фокусируется, когда я вызываю AlertDialog.show(), но программная клавиатура не отображается автоматически.

Как сделать так, чтобы программная клавиатура автоматически отображалась при отображении диалогового окна? (и нет физической / аппаратной клавиатуры). Аналогично тому, как когда я нажимаю кнопку «Поиск», чтобы вызвать глобальный поиск, автоматически отображается программная клавиатура.

Ответы [ 25 ]

292 голосов
/ 10 марта 2010

Вы можете создать фокус слушателя на EditText на AlertDialog, а затем получить AlertDialog 'Window. Оттуда вы можете показать экранную клавиатуру, позвонив по номеру setSoftInputMode.

.
final AlertDialog dialog = ...;

editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (hasFocus) {
            dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
        }
    }
});
218 голосов
/ 22 июня 2012

Для отображения клавиатуры используйте:

InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);

Для сокрытия клавиатуры используйте:

InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(),0); 
109 голосов
/ 05 ноября 2011

Вы можете запросить программную клавиатуру сразу после создания диалога (тест на SDK - r20)

// create dialog
final AlertDialog dialog = ...; 

// request keyboard   
dialog.getWindow().setSoftInputMode (WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
24 голосов
/ 11 октября 2011

У меня была такая же проблема, и я решил ее с помощью следующего кода. Я не уверен, как он будет вести себя на телефоне с аппаратной клавиатурой.

// TextEdit
final EditText textEdit = new EditText(this);

// Builder
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle("Enter text");
alert.setView(textEdit);

alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        String text = textEdit.getText().toString();
        finish();
    }
});

alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        finish();
    }
});

// Dialog
AlertDialog dialog = alert.create();
dialog.setOnShowListener(new OnShowListener() {

    @Override
    public void onShow(DialogInterface dialog) {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.showSoftInput(textEdit, InputMethodManager.SHOW_IMPLICIT);
    }
});

dialog.show();
22 голосов
/ 28 февраля 2012

Я нашел этот пример http://android -codes-examples.blogspot.com / 2011/11 / show-or-hide-soft-клавиатура-на-открытии.html . Добавьте следующий код непосредственно перед alert.show().

InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);
16 голосов
/ 06 сентября 2013
<activity
    ...
    android:windowSoftInputMode="stateVisible" >
</activity>

или

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
14 голосов
/ 17 декабря 2015

Фрагменты кода из других ответов работают, но не всегда очевидно, где разместить их в коде, особенно если вы используете AlertDialog.Builder и следовали официальному учебнику по диалогу , потому что он не ' т final AlertDialog ... или alertDialog.show().

alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);

Предпочтительнее

InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);

Поскольку SOFT_INPUT_STATE_ALWAYS_VISIBLE будет скрывать клавиатуру, если фокус переключается с EditText, где SHOW_FORCED будет отображать клавиатуру до тех пор, пока она не будет явно отклонена, даже если пользователь возвращается на домашний экран или отображает последние приложения.

Ниже приведен рабочий код для AlertDialog, созданного с использованием пользовательского макета с EditText, определенным в XML. Он также устанавливает на клавиатуре клавишу «go» и позволяет ей активировать положительную кнопку.

alert_dialog.xml:

<RelativeLayout
android:id="@+id/dialogRelativeLayout"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >

    <!-- android:imeOptions="actionGo" sets the keyboard to have a "go" key instead of a "new line" key. -->
    <!-- android:inputType="textUri" disables spell check in the EditText and changes the "go" key from a check mark to an arrow. -->
    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:layout_marginLeft="4dp"
        android:layout_marginRight="4dp"
        android:layout_marginBottom="16dp"
        android:imeOptions="actionGo"
        android:inputType="textUri"/>

</RelativeLayout>

AlertDialog.java:

import android.app.Activity;
import android.app.Dialog;
import android.content.DialogInterface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatDialogFragment;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.EditText;

public class CreateDialog extends AppCompatDialogFragment {
    // The public interface is used to send information back to the activity that called CreateDialog.
    public interface CreateDialogListener {
        void onCreateDialogCancel(DialogFragment dialog);    
        void onCreateDialogOK(DialogFragment dialog);
    }

    CreateDialogListener mListener;

    // Check to make sure that the activity that called CreateDialog implements both listeners.
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mListener = (CreateDialogListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement CreateDialogListener.");
        }
    }

    // onCreateDialog requires @NonNull.
    @Override
    @NonNull
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity());
        LayoutInflater customDialogInflater = getActivity().getLayoutInflater();

        // Setup dialogBuilder.
        alertDialogBuilder.setTitle(R.string.title);
        alertDialogBuilder.setView(customDialogInflater.inflate(R.layout.alert_dialog, null));
        alertDialogBuilder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                mListener.onCreateDialogCancel(CreateDialog.this);
            }
        });
        alertDialogBuilder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                mListener.onCreateDialogOK(CreateDialog.this);
            }
        });

        // Assign the resulting built dialog to an AlertDialog.
        final AlertDialog alertDialog = alertDialogBuilder.create();

        // Show the keyboard when the dialog is displayed on the screen.
        alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);

        // We need to show alertDialog before we can setOnKeyListener below.
        alertDialog.show();

        EditText editText = (EditText) alertDialog.findViewById(R.id.editText);

        // Allow the "enter" key on the keyboard to execute "OK".
        editText.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, select the PositiveButton "OK".
                if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {
                    // Trigger the create listener.
                    mListener.onCreateDialogOK(CreateDialog.this);

                    // Manually dismiss alertDialog.
                    alertDialog.dismiss();

                    // Consume the event.
                    return true;
                } else {
                    // If any other key was pressed, do not consume the event.
                    return false;
                }
            }
        });

        // onCreateDialog requires the return of an AlertDialog.
        return alertDialog;
    }
}
11 голосов
/ 11 октября 2015

Ну, это довольно старый пост, но есть что добавить.
Это два простых метода, которые помогают мне контролировать клавиатуру, и они работают просто отлично:

Показать клавиатуру

public void showKeyboard() {
    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    View v = getCurrentFocus();
    if (v != null)
        imm.showSoftInput(v, 0);
}

Скрыть клавиатуру

public void hideKeyboard() {
    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    View v = getCurrentFocus();
    if (v != null)
        imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
9 голосов
/ 20 декабря 2012

Позвольте мне указать дополнительную информацию о решении Юку, потому что мне было трудно заставить это работать! Как получить объект AlertDialog из моего AlertDialog.Builder? Ну, это результат моего alert.show() выполнения:

final AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());
final EditText input = new EditText(getActivity());
alert.setView(input);

// do what you need, like setting positive and negative buttons...

final AlertDialog dialog = alert.show();

input.setOnFocusChangeListener(new OnFocusChangeListener() {
   @Override
   public void onFocusChange(View v, boolean hasFocus) {
      if(hasFocus) {
         dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
      }
   }
});
7 голосов
/ 08 марта 2010

Взгляните на это обсуждение , которое обрабатывает скрытие и отображение IME вручную. Тем не менее, я чувствую, что, если сфокусированный EditText не вызывает IME, это потому, что вы вызываете AlertDialog.show() в своем OnCreate() или каком-либо другом методе, который вызывается до того, как экран действительно будет представлен. Перемещение на OnPostResume() должно исправить это в том случае, если я верю.

...