我正在使用AlertDialog显示一个输入框。当我调用AlertDialog.show()时,对话框内部的EditText会自动聚焦,但软键盘不会自动显示。

我如何使软键盘自动显示时,对话框显示?(并且没有物理/硬件键盘)。类似于当我按下Search按钮调用全局搜索时,会自动显示软键盘。


当前回答

是的,你可以用setOnFocusChangeListener来做,它会帮助你。

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

其他回答

我找到了这个例子http://android-codes-examples.blogspot.com/2011/11/show-or-hide-soft-keyboard-on-opening.html。在alert.show()之前添加以下代码。

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

来自其他答案的代码片段也可以工作,但将它们放在代码中的哪个位置并不总是很明显,特别是在使用AlertDialog时。Builder和遵循官方对话框教程,因为它不使用最终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);

因为如果焦点从EditText移开,SOFT_INPUT_STATE_ALWAYS_VISIBLE将隐藏键盘,而SHOW_FORCED将保持键盘显示,直到显式地关闭,即使用户返回到主屏幕或显示最近的应用程序。

下面是使用自定义布局和XML定义的EditText创建的AlertDialog的工作代码。它还设置键盘有一个“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;
    }
}

您可以在AlertDialog的EditText上创建一个焦点侦听器,然后获取AlertDialog的窗口。从那里你可以通过调用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);
        }
    }
});

这是一个很好的例子:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ScrollView
        android:id="@+id/scrollID"
        android:layout_width="fill_parent"
        android:layout_height="0dip"
        android:layout_weight="1" >

        <LinearLayout
            android:id="@+id/test"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >
        </LinearLayout>
    </ScrollView>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:baselineAligned="true"
        android:orientation="horizontal"
        android:paddingBottom="5dp"
        android:paddingLeft="5dp"
        android:paddingRight="5dp"
        android:weightSum="1" >

        <EditText
            android:id="@+id/txtInpuConversation"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="0.5"
            android:hint="@string/edt_Conversation" >

            <requestFocus />
        </EditText>

        <Button
            android:id="@+id/btnSend"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="0.5"
            android:text="@string/btn_Conversation" />
    </LinearLayout>

</LinearLayout>

看看这个手动隐藏和显示IME的讨论。然而,我的感觉是,如果一个集中的EditText没有带来IME,这是因为你正在调用AlertDialog.show()在你的OnCreate()或一些其他方法,在屏幕实际呈现之前被唤起。移动到OnPostResume()应该在这种情况下修复它,我相信。