Android 片段启动时显示编辑文本的键盘

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10508363/
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 03:59:53  来源:igfitidea点击:

Show keyboard for edittext when fragment starts

androidandroid-edittextandroid-softkeyboard

提问by heero

When my fragment starts, I want my edittext to be in focus/let user to just start typing in it. I am able to get it in focus with requestFocus(), but I cannot get the keyboard to show up.

当我的片段开始时,我希望我的 edittext 成为焦点/让用户开始输入它。我可以使用 requestFocus() 将其聚焦,但无法显示键盘。

I have tried both this:

我已经尝试过这两个:

edit = (EditText) view.findViewById(R.id.search);
edit.requestFocus();
InputMethodManager imgr = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imgr.showSoftInput(edit, 0);

and

edit = (EditText) view.findViewById(R.id.search);
InputMethodManager imgr = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imgr.showSoftInput(edit, 0);
edit.requestFocus();

How can I get the keyboard to show up for EditText?

如何让键盘显示 EditText?

回答by Sam

Does this work?

这行得通吗?

imgr.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);

回答by Ilya

You can try this

你可以试试这个

@Override
public void onResume() {
    super.onResume();
    edit.post(new Runnable() {
        @Override
        public void run() {
            edit.requestFocus();
            InputMethodManager imgr = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
            imgr.showSoftInput(edit, InputMethodManager.SHOW_IMPLICIT);
        }
    });
}

回答by cesards

Since using showSoftInputdoesn't work for all cases and after trying some of the solutions mentioned here, like:

由于 usingshowSoftInput不适用于所有情况,并且在尝试了此处提到的一些解决方案后,例如:

if (binding.account.requestFocus()) {
  getActivity().getWindow()
      .setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
}

I finally made it work using:

我终于让它工作了

if (binding.account.requestFocus()) {
  ((InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE)).toggleSoftInput(
      InputMethodManager.SHOW_FORCED,
      InputMethodManager.HIDE_IMPLICIT_ONLY
  );
}

Since:

自从:

 binding.account.requestFocus()

only request the focus for the EditText(it doesn't open the keyboard)

只请求焦点EditText(它不打开键盘)

and

((InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE)).toggleSoftInput(
      InputMethodManager.SHOW_FORCED,
      InputMethodManager.HIDE_IMPLICIT_ONLY
  );

is the only solution that appears to be working correctly to show the keyboard (and the most voted one)

是唯一似乎可以正常工作以显示键盘的解决方案(也是投票最多的解决方案)

Good luck! :-)

祝你好运!:-)

回答by Rafols

I have helpful extension for that:

我有有用的扩展:

fun EditText.showKeyboard() {
    if (requestFocus()) {
        (getActivity()?.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager)
            .showSoftInput(this, SHOW_IMPLICIT)
        setSelection(text.length)
    }
}

You will also need this one:

你还需要这个:

fun View.getActivity(): AppCompatActivity?{
    var context = this.context
    while (context is ContextWrapper) {
        if (context is AppCompatActivity) {
            return context
        }
        context = context.baseContext
    }
    return null
}

回答by Amin Keshavarzian

After trying all solutions here and on other questions related, Here's the method that works for me:

在尝试了所有解决方案和其他相关问题后,以下是对我有用的方法:

editText.postDelayed(Runnable { showKeyboard(activity, editText)} , 50)


fun showKeyboard(activity: Activity, editText: EditText) {
    val inputMethodManager = activity.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
    editText.requestFocus()
    inputMethodManager.showSoftInput(this, 0)
}

The fun fact is when you call it without postDeleayed it won't work, even if you just delay it for 1 millisecond it still won't work :D

有趣的事实是,当你在没有 postDeleayed 的情况下调用它时,它不会工作,即使你只是延迟 1 毫秒,它仍然不会工作:D

You can also use it as an extension like this:

您还可以将其用作这样的扩展:

fun EditText.showKeyboard(activity: Activity) {
    val inputMethodManager = activity.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
    requestFocus()
    inputMethodManager.showSoftInput(this, 0)
}

if you don't like to pass activity as a parameter, you use this extension function as @Rafols suggests:

如果您不喜欢将活动作为参数传递,则可以按照@Rafols 的建议使用此扩展函数:

fun View.getActivity(): AppCompatActivity? {
    var context = this.context
    while (context is ContextWrapper) {
        if (context is AppCompatActivity) {
            return context
        }
        context = context.baseContext
    }
    return null
}

then your method will look like this:

那么您的方法将如下所示:

fun EditText.showKeyboard() {
    val inputMethodManager = getActivity()!!.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
    requestFocus()
    inputMethodManager.showSoftInput(this, 0)
}

also if you have a text already in your EditText, its better set selection at the end of your existing text:

此外,如果您的 EditText 中已有文本,则最好在现有文本的末尾设置选择:

fun EditText.showKeyboard() {
    val inputMethodManager = getActivity()!!.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
    requestFocus()
    inputMethodManager.showSoftInput(this, 0)
    setSelection(length())
}

and if you want to start it when fragment starts:

如果您想在片段启动时启动它:

override fun onResume() {
    super.onResume()
    editText.postDelayed(Runnable { editText.showKeyboard()} , 50)
}

回答by Rubber Duck

    @Override
public void onHiddenChanged (boolean hidden)
{
    super.onHiddenChanged(hidden);

    if(hidden)
    {
        hideKeyboard(yourView);
    }
    else
    {
        toggleKeyboard(yourView);
    }
}

    public static void toggleKeyboard(View v)
{
    InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
    v.requestFocus();

    imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_NOT_ALWAYS);
}

public static void hideKeyboard(View v)
{
    InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);

    imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}

回答by Yessy

EditText.requestFocus() + InputMethodManager.showSoftInput() = Show IME for EditText

编辑文本。requestFocus() + InputMethodManager. showSoftInput() = 显示 EditText 的 IME

use EditText.performAccessibilityAction(AccessibilityNodeInfo.ACTION_CLICK, null) in Fragment.onViewCreated() instead

使用编辑文本。performAccessibilityAction(AccessibilityNodeInfo.ACTION_CLICK, null) 在 Fragment.onViewCreated() 代替

    void maybeShowInputMethod() {
        // use addOnPreDrawListener instead of addOnGlobalLayoutListener
        // because execute sequence: onGlobalLayout-> Restore focus -> onPreDraw
        getView().getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {

            @Override
            public boolean onPreDraw() {
                // TODO Auto-generated method stub
                getView().getViewTreeObserver().removeOnPreDrawListener(this);

                // always requestFocus when fragment enter or show
                getView().requestFocus();
                final View currentFocus = getView().findFocus();
                if ((currentFocus != null) && currentFocus.onCheckIsTextEditor()) {
                    Log.d(TAG, "maybeShowInputMethod:: currentFocus=" + currentFocus);
                    currentFocus.performAccessibilityAction(AccessibilityNodeInfo.ACTION_CLICK, null);
                }
                return true;
            }
        });
    }


or create subclass of EditText and override public InputConnection onCreateInputConnection(EditorInfo editorInfo)

或创建 EditText 的子类并覆盖public InputConnection onCreateInputConnection(EditorInfo editorInfo)

public class ImeAwareEditText extends EditText {
private boolean mHasPendingShowSoftInputRequest;
final Runnable mRunShowSoftInputIfNecessary = () -> showSoftInputIfNecessary();

public ImeAwareEditText(Context context) {
    super(context, null);
}

public ImeAwareEditText(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public ImeAwareEditText(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}

public ImeAwareEditText(Context context, AttributeSet attrs, int defStyleAttr,
        int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
}

/**
 * This method is called back by the system when the system is about to establish a connection
 * to the current input method.
 *
 * <p>This is a good and reliable signal to schedule a pending task to call
                                                                                                                                                                                                                     52,6          Top
 *
 * <p>This is a good and reliable signal to schedule a pending task to call
 * {@link InputMethodManager#showSoftInput(View, int)}.</p>
 *
 * @param editorInfo context about the text input field.
 * @return {@link InputConnection} to be passed to the input method.
 */
@Override
public InputConnection onCreateInputConnection(EditorInfo editorInfo) {
    final InputConnection ic = super.onCreateInputConnection(editorInfo);
    if (mHasPendingShowSoftInputRequest) {
        removeCallbacks(mRunShowSoftInputIfNecessary);
        post(mRunShowSoftInputIfNecessary);
    }
    return ic;
}

private void showSoftInputIfNecessary() {
    if (mHasPendingShowSoftInputRequest) {
        final InputMethodManager imm =
                getContext().getSystemService(InputMethodManager.class);
        imm.showSoftInput(this, 0);
        mHasPendingShowSoftInputRequest = false;
    }
}

public void scheduleShowSoftInput() {
    final InputMethodManager imm = getContext().getSystemService(InputMethodManager.class);
    if (imm.isActive(this)) {
        // This means that ImeAwareEditText is already connected to the IME.
        // InputMethodManager#showSoftInput() is guaranteed to pass client-side focus check.
        mHasPendingShowSoftInputRequest = false;
        removeCallbacks(mRunShowSoftInputIfNecessary);
        imm.showSoftInput(this, 0);
        return;
    }

    // Otherwise, InputMethodManager#showSoftInput() should be deferred after
    // onCreateInputConnection().
    mHasPendingShowSoftInputRequest = true;
}
}

回答by X-Black...

Kotlin

科特林

To automatically show/hide the keyboard in fragment...

在片段中自动显示/隐藏键盘...

override fun onResume() {
    super.onResume()

    requireView().edit_text_ID.showKeyboard()

    requireView().edit_text_ID.setOnFocusChangeListener { _, hasFocus ->
     if (!hasFocus){
        hideKeyboardFrom(requireContext(), requireView())
     }
    }
}

fun EditText.showKeyboard() {
    if (requestFocus()) {
        (activity?.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager)
            .showSoftInput(this, SHOW_IMPLICIT)
        setSelection(text.length)
    }
}

fun hideKeyboardFrom(context: Context, view: View) {
    val imm =
        context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
    imm.hideSoftInputFromWindow(view.windowToken, 0)
}

A little piesce of info here.

这里有一些信息。

回答by sud007

Simply, using adding 2 lines will work like a charm:

简单地说,使用添加 2 行就像一个魅力:

If using XML

如果使用 XML

android:focusable="true"
android:focusableInTouchMode="true"

Else in Java:

其他在 Java 中:

view.setFocusableInTouchMode(true);
view.requestFocus();

回答by DiscDev

Another way to make the keyboard open when your fragment starts is to call requestFocus()in onCreateViewand react accordingly by opening the keyboard if and only if the EditTextis focusable.

让你的片段开始时键盘打开另一个方法是调用requestFocus()onCreateView通过打开键盘,当且仅当相应的反应EditText可获得焦点。

if(this.editText.requestFocus())
{
    getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
}