在片段替换上显示/隐藏 Android 软键盘

Posted

技术标签:

【中文标题】在片段替换上显示/隐藏 Android 软键盘【英文标题】:Show / hide Android softkeyboard on fragment replace 【发布时间】:2014-10-29 19:36:51 【问题描述】:

我有一个带有片段的活动。让我们说一个带有事物列表的列表片段。现在我想让用户添加一个东西,所以我使用 FragmentManager 将列表片段替换为具有 EditText 的插入片段。 EditText 具有焦点并且光标正在闪烁。但是软键盘打不开。 反过来也是一样:如果用户输入了新事物并将其添加到列表中,我将插入片段替换为列表片段。但是虽然没有EditText了,但是键盘并没有关闭。

实现这一点的正确方法是什么?我不敢相信我必须在所有转换中手动显示和隐藏键盘?!

【问题讨论】:

The EditText has the focus and the cursor is blinking. But the softkeyboard doesn't open. 在您的androidManifest.xml 在此活动的标签内,您是否设置了android:windowSoftInputMode="stateHidden"?如果是,则一旦用户单击EditText,则只会显示软键盘。否则不会即使焦点在 EditText 上也不会显示。 我认为你需要参考android:windowSoftInputMode documents并尝试不同的组合。然后看看你是否能找到你需要的组合。 我没有在清单中设置任何输入模式,我不相信它会有所帮助,因为它控制软键盘在进入活动时的反应。但我的问题是过渡到另一个片段。 【参考方案1】:

我会做以下事情: 1.扩展Fragment类 2. 覆盖 onAttach()onDetach() 回调 3.实现显示和隐藏软键盘方法

示例代码:

class MyFragment extends Fragment 
   @Override
   public void onAttach(Activity activity) 
       super.onAttach(activity);

       //show keyboard when any fragment of this class has been attached
       showSoftwareKeyboard(true);
   

   @Override
   public void onDetach() 
       super.onDetach();

       //hide keyboard when any fragment of this class has been detached
       showSoftwareKeyboard(false);
   

   protected void showSoftwareKeyboard(boolean showKeyboard)
       final Activity activity = getActivity();
       final InputMethodManager inputManager = (InputMethodManager)activity.getSystemService(Context.INPUT_METHOD_SERVICE);

       inputManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), showKeyboard ? InputMethodManager.SHOW_FORCED : InputMethodManager.HIDE_NOT_ALWAYS);
   

【讨论】:

很棒的家伙 .... 我花了大约 3 天 .. onAttach() 的想法救了我 ... 这应该被标记为答案【参考方案2】:

我的应用也有同样的问题,最后我们有 2 个选项,首先创建一个通用函数并在所有转换中调用它或创建一个全局转换如何:

public static void RemoveAndReplaceFragment(FragmentManager fragmentManager, int FragmentContent, Fragment PlaceHolderFragment,Activity context)
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.remove(fragmentManager.findFragmentById(R.id.frgMainActivity))
                .commit();

        //Close keyBoard in transition
        InputMethodManager inputManager = (InputMethodManager) context.getSystemService(
                Context.INPUT_METHOD_SERVICE);
        inputManager.hideSoftInputFromWindow(context.getCurrentFocus().getWindowToken(),
                InputMethodManager.HIDE_NOT_ALWAYS);

        fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.setCustomAnimations(R.anim.animation_fade_in,R.anim.animation_fade_out);
        fragmentTransaction.replace(R.id.frgMainActivity, new PlaceholderFragment_MainActivity_AcceptAndFollowTask()).commit();
    

最好的方法是捕捉过渡事件,但我们现在不能...告诉我如果我能帮助你,祝你好运!

【讨论】:

【参考方案3】:

这肯定会起作用:

private void hideKeyboard()    
    // Check if no view has focus:
    View view = this.getCurrentFocus();
    if (view != null) 
        InputMethodManager inputManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
        inputManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
    

    private void showKeyboard()
    EditText myEditText = (EditText) findViewById(R.id.myEditText);  
    InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(myEditText.getWindowToken(), 0);
   

【讨论】:

【参考方案4】:

我猜你的ListView 正在窃取你EditText 的焦点,试试这个,如果有帮助,请告诉我。

getListView().setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);

【讨论】:

【参考方案5】:

试试这个

InputMethodManager imgr = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);

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

【讨论】:

【参考方案6】:

我同意,我不敢相信您还必须手动隐藏键盘。

将此添加到您不希望键盘不在的 Fragment onCreate:

   ((InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(mToolbar.getWindowToken(), 0);

将 mToolbar 更改为布局中的任何视图。在这种情况下,我使用了我的工具栏。

将此添加到您希望显示键盘的 Fragment onCreate。

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

【讨论】:

【参考方案7】:

您可以使用下面的代码来隐藏软键盘。

InputMethodManager inputManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); 
inputManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(),InputMethodManager.HIDE_NOT_ALWAYS);

【讨论】:

【参考方案8】:

对于 Kotlin:

    将此函数放在 Utils 类之类的地方。
fun hideSoftKeyboard(view: View, context: Context) 
        val inputMethodManager = 
            context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0)
    

然后在片段或活动中使用它:


Utils().hideSoftKeyboard(inputTextChat, requireContext())

【讨论】:

【参考方案9】:

一种方法是调用Activity.recreate,因为无论如何都需要处理方向更改的情况。看起来有点矫枉过正,而且你最终也会得到不同的过渡动画。

【讨论】:

以上是关于在片段替换上显示/隐藏 Android 软键盘的主要内容,如果未能解决你的问题,请参考以下文章

软键盘显示与隐藏的监听

Android软键盘弹出和收回监听

在 Toast 下保留软键盘 - ANDROID

软输入键盘隐藏编辑文本

Android开发常用工具总结

Android 软键盘控制方法以及开发中遇到的一些问题。