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

26

我有一个带有Fragment的Activity。假设是一个包含一组事物的列表Fragment。现在我想让用户添加一个事物,所以我使用FragmentManager将列表Fragment替换为具有EditText的插入Fragment。 EditText获得焦点且光标闪烁。但软键盘不会打开。 同样的问题反过来:如果用户输入了新事物并将其添加到列表中,我会用列表Fragment替换插入Fragment。但是,即使没有EditText,键盘也不会关闭。

如何正确实现这一点?我无法相信在所有转换中都必须手动显示和隐藏键盘?!


EditText已经获得了焦点,光标也在闪烁。但是软键盘没有弹出。请检查你的AndroidManifest.xml文件中是否在该活动的标签内设置了"android:windowSoftInputMode="stateHidden""。如果是,则只有当用户点击EditText时才会显示软键盘。否则,即使焦点在EditText上,软键盘也不会显示。 - Sash_KP
我认为您需要查阅android:windowSoftInputMode documents并尝试不同的组合。然后看看是否可以找到所需的组合。 - Sash_KP
我在清单文件中没有设置任何输入模式,而且我认为这并不会有帮助,因为它只控制软键盘在进入 Activity 时的反应。但我的问题是转换到另一个片段。 - Maniac
9个回答

12
我想要做以下事情:

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() 这个想法拯救了我... - karthik kolanji
这应该被标记为答案。 - aya salama

3

我遇到了和我的应用相同的问题,最终我们有两个选择:第一种是创建一个通用函数,在所有的过渡中调用它;第二种是创建一个全局过渡,具体方法如下:

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

最好的方法是捕获过渡事件,但目前我们无法做到...如果我能帮上你什么忙,请告诉我,祝你好运!


1
这肯定会起作用:


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

0

对于 Kotlin:

  1. 将此函数放置在类似 Utils 类的某个位置。
fun hideSoftKeyboard(view: View, context: Context) {
        val inputMethodManager = 
            context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0)
    }

然后在Fragment或Activity中使用它,例如:


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

0
我猜测你的 ListView 正在夺取你的 EditText 的焦点,尝试这个方法,看看是否有帮助。
getListView().setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);

0

试试这个

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

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

0

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

将以下代码添加到你的Fragment onCreate中,以不显示键盘:

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

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

将此代码添加到您希望显示键盘的片段的onCreate方法中。

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

0

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

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接