【问题标题】:How to hide the soft keyboard inside a fragment?如何将软键盘隐藏在片段中?
【发布时间】:2011-12-17 22:51:49
【问题描述】:

我有一个FragmentActivity 使用ViewPager 来服务多个片段。每个都是ListFragment,布局如下:

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

        <EditText android:id="@+id/entertext"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>
</LinearLayout>

启动活动时,软键盘显示。为了解决这个问题,我在片段中执行了以下操作:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    //Save the container view so we can access the window token
    viewContainer = container;
    //get the input method manager service
    imm = (InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
    . . .
}

@Override
public void onStart() {
    super.onStart();

    //Hide the soft keyboard
    imm.hideSoftInputFromWindow(viewContainer.getWindowToken(), 0);
}

我保存来自onCreateView 的传入ViewGroup container 参数作为访问主要活动的窗口令牌的一种方式。这运行没有错误,但在onStart 中对hideSoftInputFromWindow 的调用不会隐藏键盘。

最初,我尝试使用膨胀布局而不是container,即:

imm.hideSoftInputFromWindow(myInflatedLayout.getWindowToken(), 0);

但这抛出了一个NullPointerException,大概是因为片段本身不是一个活动并且没有唯一的窗口令牌?

有没有办法在片段中隐藏软键盘,或者我应该在FragmentActivity 中创建一个方法并在片段中调用它?

【问题讨论】:

    标签: java android kotlin android-fragments android-softkeyboard


    【解决方案1】:

    只要您的 Fragment 创建一个视图,您就可以在附加视图之后使用 IBinder(窗口令牌)。例如,您可以在 Fragment 中覆盖 onActivityCreated:

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        final InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(getView().getWindowToken(), 0);
    }
    

    【讨论】:

    • 我将此添加到我的项目中。但是当我单击另一个选项卡时它崩溃了。
    • 对于那些正在这样做并因 NullPointerException 而崩溃的人,只需在片段 onCreateView 方法中使用 InputMethodManager。这样做,您将拥有自己的视图,并且您可以使用已膨胀为 imm.hideSoftInputFromWindow(view.getWindowToken(), 0); 的视图更改最后一行
    • 完美答案,我建议在 Resume 上添加相同的功能来处理它,以防在 viewpager 内创建了许多片段并且其中一个片段需要在创建后隐藏键盘
    【解决方案2】:

    除了以下代码行对我有用:

    getActivity().getWindow().setSoftInputMode(
                WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
    

    【讨论】:

    • SOFT_INPUT_STATE_HIDDEN 也对我有用,虽然我不知道这和 `SOFT_INPUT_STATE_ALWAYS_HIDDEN' 有什么区别。
    • 第一个答案没有用,这个成功了。谢谢
    • 感谢您节省我的时间的朋友。
    • 我的情况是我正在使用片段/TabView。第一个选项卡在 TextView 中有“提示”。第二个选项卡有一个活动,其中我有 EditText(s) 和“editText1.setShowSoftInputOnFocus(false);”命令集和我自己的自定义键盘。当我将应用程序置于后台,然后将应用程序带回视图时,会弹出不需要的软键盘。在 onStart Life Cycle Override 方法中设置上述命令会停止此操作。谢谢@Shajeel Afzal
    【解决方案3】:

    如果您将以下属性添加到 Activity 的清单定义中,它将完全抑制键盘在您的 Activity 打开时弹出。希望这会有所帮助:

    (添加到 Activity 的清单定义中):

    android:windowSoftInputMode="stateHidden"
    

    【讨论】:

    • 谢谢,这就是我最终要做的。但是,我仍然想知道如何使用输入法管理器来显示/隐藏键盘,因为我可能需要在活动开始后的某个时间使用它。
    【解决方案4】:
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_my, container,
                    false);
            someClass.onCreate(rootView);
            return rootView;
        }
    

    在我的班级中保留我的根视图的实例

    View view;
    
    public void onCreate(View rootView) {
        view = rootView;
    

    使用视图隐藏键盘

     public void removePhoneKeypad() {
        InputMethodManager inputManager = (InputMethodManager) view
                .getContext()
                .getSystemService(Context.INPUT_METHOD_SERVICE);
    
        IBinder binder = view.getWindowToken();
        inputManager.hideSoftInputFromWindow(binder,
                InputMethodManager.HIDE_NOT_ALWAYS);
    }
    

    【讨论】:

    • 我使用了这个,但我使用了片段中的 getView() 而不是保留视图的实例。
    • onCreate 是 Fragment 之外的一个类,所以我将它传递给 rootView 以便能够使用它来删除该类中的 phoneKeyPad。我想他们想要从 Fragment 内部而不是 Fragment 中的一个类。
    【解决方案5】:

    DialogFragment 的例外情况是,必须隐藏嵌入的Dialog 的焦点,而只能隐藏嵌入的Dialog 中的第一个EditText

    this.getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
    

    【讨论】:

    • 如果您有 DialogFragment,这是隐藏键盘的唯一方法。
    • 在哪里写这个?
    • @Mstack,适用于 onActivityCreated() 方法。override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN)}
    【解决方案6】:

    此代码适用于片段:

    getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
    

    【讨论】:

      【解决方案7】:

      在您喜欢的任何地方(活动/片段)使用此静态方法。

      public static void hideKeyboard(Activity activity) {
          try{
              InputMethodManager inputManager = (InputMethodManager) activity
                      .getSystemService(Context.INPUT_METHOD_SERVICE);
              View currentFocusedView = activity.getCurrentFocus();
              if (currentFocusedView != null) {
                  inputManager.hideSoftInputFromWindow(currentFocusedView.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
              }
          }catch (Exception e){
              e.printStackTrace();
          }
      }
      

      如果你想使用片段,只需调用hideKeyboard(((Activity) getActivity()))

      【讨论】:

        【解决方案8】:

        当我在标签中从一个片段切换到另一个片段时,这将适用于我的情况

        @Override
        public void setUserVisibleHint(boolean isVisibleToUser) {
            super.setUserVisibleHint(isVisibleToUser);
            if (isVisibleToUser) {
                try {
                    InputMethodManager mImm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
                    mImm.hideSoftInputFromWindow(getView().getWindowToken(), 0);
                    mImm.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0);
                } catch (Exception e) {
                    Log.e(TAG, "setUserVisibleHint: ", e);
                }
            }
        }
        

        【讨论】:

        • 如果你有标签片段并且只想隐藏几个标签的键盘,使用这个。
        【解决方案9】:

        这一切都不适用于 API27。我必须在布局的容器中添加它,对我来说它是一个 ConstraintLayout:

        <android.support.constraint.ConstraintLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:focusable="true"
                    android:focusableInTouchMode="true"
                    android:focusedByDefault="true">
        
        //Your layout
        
        </android.support.constraint.ConstraintLayout>
        

        【讨论】:

        • 它不适用于 api
        【解决方案10】:

        这在 Kotlin 课程中对我有用

        fun hideKeyboard(activity: Activity) {
            try {
                val inputManager = activity
                    .getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
                val currentFocusedView = activity.currentFocus
                if (currentFocusedView != null) {
                    inputManager.hideSoftInputFromWindow(currentFocusedView.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        
        }
        

        【讨论】:

        • 兄弟,你刚刚为我节省了超过 48 小时的工作时间!
        【解决方案11】:

        对我有用的解决方案:

        fun hideKeyboard(){
            val imm = requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
            imm.hideSoftInputFromWindow(view?.windowToken, 0)
        }
        

        在活动中:

        fun hideKeyboard(){
            val inputManager: InputMethodManager = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
            inputManager.hideSoftInputFromWindow(currentFocus?.windowToken, InputMethodManager.SHOW_FORCED)
        }
        

        【讨论】:

          【解决方案12】:

          在任何片段按钮监听器中使用此代码:

          InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(getActivity().INPUT_METHOD_SERVICE);
          imm.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0);
          

          【讨论】:

          • 有效,但您必须检查getActivity().getCurrentFocus().getWindowToken() 是否不为空,否则如果没有聚焦的editText,则会导致错误。请参阅下面的答案
          【解决方案13】:

          Kotlin 代码

          val imm = requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
          imm.hideSoftInputFromWindow(requireActivity().currentFocus?.windowToken, 0)
          

          【讨论】:

            【解决方案14】:

            只需在您的代码中添加这一行:

            getActivity().getWindow().setSoftInputMode(
                            WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
            

            【讨论】:

              【解决方案15】:

              在 Kotlin 中:

              (activity?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager).hideSoftInputFromWindow(view?.windowToken,0)
              

              【讨论】:

                【解决方案16】:

                使用这个:

                Button loginBtn = view.findViewById(R.id.loginBtn);
                loginBtn.setOnClickListener(new View.OnClickListener() {
                   public void onClick(View v) {
                      InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(getActivity().INPUT_METHOD_SERVICE);
                      imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
                   }
                });
                

                【讨论】:

                  【解决方案17】:

                  开始

                  在片段中,下面的代码(在 onActivityCreated 中使用)强制在开头隐藏键盘:

                  @Override
                  public void onActivityCreated(@Nullable Bundle savedInstanceState) {
                      super.onActivityCreated(savedInstanceState);
                  
                      Objects.requireNonNull(getActivity()).getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
                  }
                  

                  片段期间(如果需要)

                  如果你有edittext或其他不同的需要键盘,并且想在键盘外按下时隐藏键盘(在我的例子中,我在xml中有LinearLayout类),首先初始化布局:

                  LinearLayout linearLayout;
                  
                  @Override
                  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
                      
                      View view = inflater.inflate(R.layout.<your fragment xml>, container, false);
                  
                      linearLayout= view.findViewById(R.id.linearLayout);
                      ...
                      return view;
                  }
                  

                  然后,您需要以下代码(在 onViewCreated 中使用):

                  @Override
                  public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
                  
                      linearLayout.setOnClickListener(new View.OnClickListener() {
                          @Override
                          public void onClick(View view12) {
                              try {
                                  InputMethodManager inputMethodManager = (InputMethodManager) Objects.requireNonNull(VideoFragment.this.getActivity()).getSystemService(INPUT_METHOD_SERVICE);
                                  assert inputMethodManager != null;
                                  inputMethodManager.hideSoftInputFromWindow(VideoFragment.this.getActivity().getCurrentFocus().getWindowToken(), 0);
                  
                              } catch (Exception e) {
                                  e.printStackTrace();
                              }
                          }
                      });
                  
                  }
                  

                  【讨论】:

                    【解决方案18】:

                    你可以使用两种方式:

                    你可以在 Fragment 中创建一个方法,但首先你必须创建一个 View 属性并将 inflater 结果放入其中,然后在 onCreateView 中返回:

                    1° 打开你的 Fragment 课程。创建属性

                    private View view;
                    

                    2°在onCreateView中为inflater分配'view'属性

                    @Nullable
                    @Override
                    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
                                    view = inflater.inflate(R.layout.your_activity_main, container, false);
                                    return view;
                    }
                    

                    3°创建方法'hideKeyboard'

                    public void hideKeyboard(Activity activity) {
                            try{
                                InputMethodManager inputManager = (InputMethodManager) activity
                                        .getSystemService(view.getContext().INPUT_METHOD_SERVICE);
                                View currentFocusedView = activity.getCurrentFocus();
                                if (currentFocusedView != null) {
                                    inputManager.hideSoftInputFromWindow(currentFocusedView.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
                                }
                            }catch (Exception e){
                                e.printStackTrace();
                            }
                        }
                    

                    5° 现在只需调用方法

                        hideKeyboard(getActivity());
                    

                    如果这不能解决您的问题,您可以尝试将 MainActivity 类作为对象传递以关闭 Frament 类中的键盘

                    1°在你实例化Fragment的YourClassActivity中,创建方法'hideKeyboard'

                    public class YourClassActivity extends AppCompatActivity {
                        public static void hideKeyboard(Activity activity) {
                                InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
                                //Find the currently focused view, so we can grab the correct window token from it.
                                View view = activity.getCurrentFocus();
                                //If no view currently has focus, create a new one, just so we can grab a window token from it
                                if (view == null) {
                                    view = new View(activity);
                                }
                                imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
                            }
                    }
                    

                    2° 在您的 Activity 中实现“Serializable”接口以实例化 Fragment

                    public class YourClassActivity extends AppCompatActivity implements Serializable {
                    ...
                    }
                    

                    3° 当你在Activity中实例化Fragment时,你必须将参数传递给那个Fragment,它就是Activity类本身

                    Bundle bundle = new Bundle();
                    bundle.putSerializable("activity", this);
                    YourClassFragment fragment = new YourClassFragment();
                    fragment.setArguments(bundle);
                    

                    4° 现在让我们开始你的 Fragment 课程。创建属性视图和活动。

                    private View view;  
                    private Activity activity;
                    

                    5° 在onCreateView 中将'view' 属性分配给inflater。在这里,您将检索作为此 Fragment 的参数传递的 Activity 对象

                        @Nullable
                        @Override
                        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
                                view = inflater.inflate(R.layout.your_activity_main, container, false);
                                activity = (Activity) getArguments().getSerializable("obj");
                        
                                return view;
                        }
                    

                    6° 现在只需调用方法

                    hideKeyboard(activity);
                    

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 2023-04-02
                      • 1970-01-01
                      • 2023-01-09
                      • 2014-10-29
                      • 2015-09-29
                      • 1970-01-01
                      • 2011-12-24
                      相关资源
                      最近更新 更多