如何从片段内部隐藏软键盘?


82

我有一个FragmentActivity使用AViewPager服务几个片段。每个都是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);
}

我将传入的ViewGroup container参数保存onCreateView为一种访问主要活动的窗口令牌的方式。这样可以正常运行,但是不会打扰hideSoftInputFromWindowin的键盘onStart

最初,我尝试使用膨胀布局代替container,即:

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

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

是否可以从片段中隐藏软键盘,还是应该在中创建一个方法FragmentActivity并从片段中调用它?

Answers:


179

只要您的片段创建了一个视图,就可以在附加了该视图之后从该视图使用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);
}

9
我将此添加到我的项目中。但是,当我单击另一个选项卡时,它崩溃了。
andro-girl

4
对于那些正在执行此操作并因NullPointerException而崩溃的人,只需在片段的onCreateView方法内使用InputMethodManager。这样做,您将拥有自己的视图,并且可以使用放大后的视图更改为imm.hideSoftInputFromWindow(view.getWindowToken(),0);来更改最后一行。
Aurasphere

83

以下几行代码仅对我有用:

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

1
SOFT_INPUT_STATE_HIDDEN也为我工作,尽管我不知道它和“ SOFT_INPUT_STATE_ALWAYS_HIDDEN”之间的区别是什么。
hBrent

2
第一个答案无效,这个技巧起作用了。谢谢
moujib

1
感谢您节省我的时间。
哈里斯·雷迪

我的情况是我正在使用fragment / TabView。第一个选项卡在TextView中具有“提示”。第二个选项卡有一个活动,其中我有带有“ editText1.setShowSoftInputOnFocus(false);”的EditText(s)。命令集和我自己的自定义键盘。当我将应用程序置于后台,然后将其重新显示时,会弹出不需要的软键盘。在onStart Life Cycle Override方法中设置上述命令将停止此操作。感谢@Shajeel Afzal
永远是CS学生

21

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

(添加到“活动”的清单定义中):

android:windowSoftInputMode="stateHidden"

谢谢,这就是我最后要做的。但是,我仍然想知道如何使用输入法管理器来显示/隐藏键盘,因为在活动开始后的某个时间我可能需要使用它。
WilHall 2011年

12
    @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()而不是保留视图的实例。
MrEngineer13

onCreate是Fragment之外的一个类,因此我将rootView传递给它,以便能够使用它删除此类中的phoneKeyPad。我想他们想从Fragment内部获取它,而不是Fragment中的类。
移动应用程序

10

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

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

5
如果您有DialogFragment,这是隐藏键盘的唯一方法。
Matjaz Kristl

在哪里写这个?
Mstack '16

@Mstack用于onActivityCreated()方法。override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN)}
Sami Issa

7

此代码适用于片段:

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

4

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

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


3

在我的情况下,当在选项卡中我从一个片段切换到另一个片段时,这将起作用

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

如果您有选项卡片段,并且只想隐藏几个选项卡的键盘,请使用此选项。
罗尼·苏里斯蒂奥

1

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 <26上不起作用,但是这样做(在片段类内部)@Override public void onResume(){super.onResume(); getView()。setFocusable(true); getView()。setFocusableInTouchMode(true); getView()。requestFocus(); }
达科

1

这在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()
    }

}

1

在任何片段按钮侦听器中使用以下代码:

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

可以,但是您必须检查是否getActivity().getCurrentFocus().getWindowToken()不为null,否则,如果没有焦点的editText,则会导致错误。请参阅下面的答案
Duc Trung Mai,

0

只需在您的代码中添加以下行:

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

0

在科特林:

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

0

用这个:

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);
   }
});
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.