Android:当焦点在 EditText 上时自动显示软键盘

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2403632/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 05:43:35  来源:igfitidea点击:

Android: show soft keyboard automatically when focus is on an EditText

androidkeyboardandroid-edittextsoft-keyboard

提问by Randy Sugianto 'Yuku'

I'm showing an input box using AlertDialog. The EditTextinside the dialog itself is automatically focused when I call AlertDialog.show(), but the soft keyboard is not automatically shown.

我正在使用AlertDialog. 在EditText该对话框中本身自动对焦,当我打电话AlertDialog.show(),但软键盘未自动显示。

How do I make the soft keyboard automatically show when the dialog is shown? (and there is no physical/hardware keyboard). Similar to how when I press the Search button to invoke the global search, the soft keyboard is automatically shown.

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

采纳答案by Randy Sugianto 'Yuku'

You can create a focus listener on the EditTexton the AlertDialog, then get the AlertDialog's Window. From there you can make the soft keyboard show by calling setSoftInputMode.

您可以在创建一个焦点侦听器EditTextAlertDialog,然后得到AlertDialogWindow。从那里你可以通过调用来显示软键盘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);
        }
    }
});

回答by horkavlna

For showing keyboard use:

用于显示键盘使用:

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

For hiding keyboard use:

隐藏键盘使用:

InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(),0); 

回答by Bao Le

You can request a soft keyboard right after creating the dialog (test on SDK - r20)

您可以在创建对话框后立即请求软键盘(在 SDK 上测试 - r20)

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

// request keyboard   
dialog.getWindow().setSoftInputMode (WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);

回答by tidbeck

I had the same problem and solved it with the following code. I'm not sure how it will behave on a phone with hardware keyboard.

我遇到了同样的问题并使用以下代码解决了它。我不确定它在带有硬件键盘的手机上的表现如何。

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

回答by Jurie Otto

I found this example http://android-codes-examples.blogspot.com/2011/11/show-or-hide-soft-keyboard-on-opening.html. Add the following code just before alert.show().

我发现这个例子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);

回答by ahtartam

<activity
    ...
    android:windowSoftInputMode="stateVisible" >
</activity>

or

或者

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);

回答by Soren Stoutner

Snippets of code from other answers work, but it is not always obvious where to place them in the code, especially if you are using an AlertDialog.Builderand followed the official dialog tutorialbecause it doesn't use final AlertDialog ...or alertDialog.show().

来自其他答案的代码片段有效,但将它们放在代码中的位置并不总是很明显,特别是如果您使用 anAlertDialog.Builder并遵循官方对话教程,因为它不使用final AlertDialog ...or alertDialog.show()

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

Is preferable to

更可取

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

Because SOFT_INPUT_STATE_ALWAYS_VISIBLE will hide the keyboard if the focus switches away from the EditText, where SHOW_FORCED will keep the keyboard displayed until it is explicitly dismissed, even if the user returns to the homescreen or displays the recent apps.

因为 SOFT_INPUT_STATE_ALWAYS_VISIBLE 将在焦点从 EditText 切换时隐藏键盘,其中 SHOW_FORCED 将保持键盘显示直到它被明确关闭,即使用户返回主屏幕或显示最近的应用程序。

Below is working code for an AlertDialog created using a custom layout with an EditText defined in XML. It also sets the keyboard to have a "go" key and allows it to trigger the positive button.

下面是使用自定义布局创建的 AlertDialog 的工作代码,其中 EditText 在 XML 中定义。它还将键盘设置为具有“go”键并允许它触发正按钮。

alert_dialog.xml:

警报对话框.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:

警报对话框.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;
    }
}

回答by sberezin

Well, this is a pretty old post, still there is something to add.
These are 2 simple methods that help me to keep keyboard under control and they work just perfect:

嗯,这是一个很老的帖子,仍然有一些东西要补充。
这些是 2 种简单的方法,可以帮助我控制键盘,并且它们工作得非常完美:

Show keyboard

显示键盘

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

Hide keyboard

隐藏键盘

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

回答by user1344313

Let me point some additional info to the solution of yuku, because I found it hard to get this working! How do I get the AlertDialog object from my AlertDialog.Builder? Well, it's the result of my alert.show()execution:

让我为 yuku 的解决方案提供一些额外的信息,因为我发现它很难让它工作!如何从 AlertDialog.Builder 获取 AlertDialog 对象?嗯,这是我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);
      }
   }
});

回答by jqpubliq

Take a look at thisdiscussion which handles manually hiding and showing the IME. However, my feeling is that if a focused EditTextis not bringing the IME up it is because you are calling AlertDialog.show()in your OnCreate()or some other method which is evoked before the screen is actually presented. Moving it to OnPostResume()should fix it in that case I believe.

看看这个处理手动隐藏和显示 IME 的讨论。但是,我的感觉是,如果一个焦点EditText没有启动 IME,那是因为您正在调用AlertDialog.show()您的OnCreate()或其他一些在实际呈现屏幕之前调用的方法。OnPostResume()在这种情况下,我相信将它移动到应该修复它。