97

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?

Quick learner
  • 10,632
  • 4
  • 45
  • 55
WilHall
  • 11,644
  • 6
  • 31
  • 53

19 Answers19

199

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);
}
Ian G. Clifton
  • 9,349
  • 2
  • 33
  • 34
  • 9
    i added this to my project.but when i click on another tab it is crashing. – andro-girl May 07 '12 at 07:14
  • 4
    For those who are doing this and getting a crash with a NullPointerException, just use the InputMethodManager inside your fragment onCreateView method. Doing so, you will have your view and you can change the last line using the view you have inflated to imm.hideSoftInputFromWindow(view.getWindowToken(), 0); – Aurasphere Oct 08 '16 at 15:47
  • perfect answer , and I suggest to add same function to on Resume to handle it in case of many fragments created inside viewpager and one of them need to hide keypad after created – Sherif farid Apr 27 '21 at 00:51
  • Thanks, but this method was deprecated. It's better to suggest another solution... – Mohamad Seyedi Mar 04 '23 at 15:33
89

Nothing but the following line of code worked for me:

getActivity().getWindow().setSoftInputMode(
            WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
Shajeel Afzal
  • 5,913
  • 6
  • 43
  • 70
  • 2
    `SOFT_INPUT_STATE_HIDDEN` also worked for me, though I don't know what the difference between that and `SOFT_INPUT_STATE_ALWAYS_HIDDEN' is. – hBrent Nov 13 '14 at 21:28
  • 2
    The first answer didn't work , this one did the trick . Thanks – moujib Aug 02 '16 at 21:22
  • 1
    Thanks for saving my time buddy. – Harish Reddy Oct 09 '18 at 18:40
  • My situation is I am using fragment/TabView. The first tab has "Tips" in a TextView. The second tab has an activity where I have EditText(s) with "editText1.setShowSoftInputOnFocus(false);" command set and my own custom keypad. When I put the app to the background and then bring the app back into view the unwanted soft keyboard would pop-up. Setting the above command in the onStart Life Cycle Override method stops this. Thanks @Shajeel Afzal –  Jun 01 '20 at 03:03
23

If you add the following attribute to your activity's manifest definition, it will completely suppress the keyboard from popping when your activity opens. Hopefully this helps:

(Add to your Activity's manifest definition):

android:windowSoftInputMode="stateHidden"
Eric Schlenz
  • 2,551
  • 20
  • 19
  • Thanks, this is what I ended up doing. However, I would still like to know how to use the Input Method Manager to show/hide the keyboard, because I might need to use it sometime after the activity starts. – WilHall Nov 09 '11 at 20:00
14
    @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;
    }

Keep an instance of my root view in my class

View view;

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

Use the view to hide the keyboard

 public void removePhoneKeypad() {
    InputMethodManager inputManager = (InputMethodManager) view
            .getContext()
            .getSystemService(Context.INPUT_METHOD_SERVICE);

    IBinder binder = view.getWindowToken();
    inputManager.hideSoftInputFromWindow(binder,
            InputMethodManager.HIDE_NOT_ALWAYS);
}
MrEngineer13
  • 38,642
  • 13
  • 74
  • 93
  • I used this but I used getView() from my fragment instead of keeping an instance of my view. – MrEngineer13 Aug 29 '15 at 15:11
  • The onCreate is a class outside the Fragment, so I pass it the rootView to be able to use it to remove the phoneKeyPad in this class. I suppose they wanted it from inside the Fragment not a class in the Fragment. – Mobile Applications Mar 05 '16 at 09:14
11

Exception for DialogFragment though, focus of the embedded Dialog must be hidden, instead only the first EditText within the embedded Dialog

this.getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
macio.Jun
  • 9,647
  • 1
  • 45
  • 41
  • 5
    This is the only way to hide keybord, if you have DialogFragment. – Matjaz Kristl Jul 03 '14 at 07:38
  • where to write this? – Mstack Oct 26 '16 at 07:04
  • @Mstack, works on onActivityCreated() method.`override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN)} ` – Sami Issa Jan 14 '20 at 08:06
9

This code works for fragments:

getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
Andre Thiele
  • 3,202
  • 3
  • 20
  • 43
Keshav Gera
  • 10,807
  • 1
  • 75
  • 53
5

Use this static method, from anywhere (Activity / Fragment) you like.

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

If you want to use for fragment just call hideKeyboard(((Activity) getActivity())).

Nazmus Saadat
  • 973
  • 9
  • 22
4

Solution that worked for me in fragments:

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

and in an activity:

fun hideKeyboard(){
    val inputManager: InputMethodManager = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    inputManager.hideSoftInputFromWindow(currentFocus?.windowToken, InputMethodManager.SHOW_FORCED)
}
Ali Nawaz
  • 2,016
  • 20
  • 30
3

this will be work in my case when in tabs i switch from one fragment to another fragments

@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);
        }
    }
}
Meerz
  • 158
  • 1
  • 10
2

Nothing of this worked on API27. I had to add this in the container of the layout, for me it was a 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>
hiddeneyes02
  • 2,562
  • 1
  • 31
  • 58
  • it doesn't work on api < 26, but this does (inside fragment class) @Override public void onResume() { super.onResume(); getView().setFocusable(true); getView().setFocusableInTouchMode(true); getView().requestFocus(); } – Dark May 15 '20 at 08:51
2

This worked for me in Kotlin class

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

}
Quick learner
  • 10,632
  • 4
  • 45
  • 55
1

In Kotlin:

(activity?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager).hideSoftInputFromWindow(view?.windowToken,0)
timeSmith
  • 553
  • 1
  • 8
  • 16
1

Use this code in any fragment button listener:

InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(getActivity().INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0);
Stan
  • 602
  • 6
  • 23
  • Works but you have to check if `getActivity().getCurrentFocus().getWindowToken()` is not null otherwise it'll cause error if there's no focused editText. See my answer below – Duc Trung Mai Sep 11 '20 at 02:48
1

Kotlin code

val imm = requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(requireActivity().currentFocus?.windowToken, 0)
RonaldPaguay
  • 337
  • 3
  • 12
0

Just add this line in you code:

getActivity().getWindow().setSoftInputMode(
                WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
Mike
  • 4,041
  • 6
  • 20
  • 37
0

Use this:

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);
   }
});
Duc Trung Mai
  • 2,141
  • 1
  • 24
  • 23
0

IN BEGINNING

in fragment, below code(use in onActivityCreated) force to hide keyboard in beginning:

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    Objects.requireNonNull(getActivity()).getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
}

DURING FRAGMENT (if need)

and also if you have edittext or sth different needs keyboard, and wanna hide the keyboard when pressing outside the keyboard(in my case I have LinearLayout class in xml), first initialize the layout:

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

then, you need to below code(use in 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();
            }
        }
    });

}
necip
  • 333
  • 4
  • 11
0

You can use two ways:

You can create a method inside fragment, but first you must create a View attribute and put the inflater result inside it before it returns in onCreateView:

1° Open your Fragment class. Create attribute

private View view;

2° assign the 'view' attribute the inflater in onCreateView

@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° create the method '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° Now just call the method

    hideKeyboard(getActivity());

If that doesn't solve your problem, you can try passing the MainActivity class as an object to close the keyboard inside the Frament class

1° In YourClassActivity that you instantiated Fragment, create the method '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° Implement the 'Serializable' interface in your Activity that instantiates the Fragment

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

3° When you instantiate the Frament in the Activity, you must pass the arguments to that Fragment, which will be the Activity class itself

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

4° Now let's go to your Fragment class. Create attribute view and activity.

private View view;  
private Activity activity;

5° Assign the 'view' attribute the inflater in onCreateView. Here you will retrieve the Activity object that was passed as a parameter of this Fragment

    @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° Now just call the method

hideKeyboard(activity);
Moises
  • 56
  • 3
0

I did all steps but there is something missing I hide the keyboard in fragments with that method

fun hideKeyBoard(view: View) {
        val inputManager =
            requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        inputManager.hideSoftInputFromWindow(
            view.windowToken,
            SOFT_INPUT_STATE_ALWAYS_HIDDEN
        )
    }

but still when I open the fragment the keyboard open also after a lot of search I found the problem I must put those code in my xml layout root

android:focusable="true"
android:focusableInTouchMode="true" 

Note: If you delete above method and just put the attributes in root layout, it will work fine.