WilHall WilHall - 21 days ago 14
Android Question

How to hide the soft keyboard from inside a fragment?

I have a

FragmentActivity
using a
ViewPager
to serve several fragments. Each is a
ListFragment
with the following layout:

<?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>


When starting the activity, the soft keyboard shows. To remedy this, I did the following inside the fragment:

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


I save the incoming
ViewGroup container
parameter from
onCreateView
as a way to access the window token for the main activity. This runs without error, but the keyboard doesn't get hidden from the call to
hideSoftInputFromWindow
in
onStart
.

Originally, I tried using the inflated layout instead of
container
, i.e:

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


but this threw a
NullPointerException
, presumably because the fragment itself isn't an activity and doesn't have a unique window token?

Is there a way to hide the soft keyboard from within a fragment, or should I create a method in the
FragmentActivity
and call it from within the fragment?

Answer

As long as your Fragment creates a View, you can use the IBinder (window token) from that view after it has been attached. For example, you can override onActivityCreated in your Fragment:

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