26

I have an Activity with a fragment. Let's say a list fragment with a list of things. Now I want to let the user add a thing, so I use the FragmentManager to replace the list fragment with an insert fragment which has an EditText. The EditText has the focus and the cursor is blinking. But the softkeyboard doesn't open. Same thing other way round: if the user has entered the new thing and added it to the list, I replace the insert fragment back with a list fragment. But although there is no EditText anymore, the keyboard doesn't close.

What is the correct way to implement this? I can't believe that I have to show and hide the keyboard manually on all transitions?!

Maniac
  • 774
  • 2
  • 7
  • 11
  • `The EditText has the focus and the cursor is blinking. But the softkeyboard doesn't open.` In your `AndroidManifest.xml` inside this activity's tag,have you set `android:windowSoftInputMode="stateHidden"`?If yes then once the user clicks on `EditText` then only softkeyboard will be shown.Else it won't be shown even if the focus is on the `EditText`. – Sash_KP Sep 04 '14 at 22:42
  • What i think is you need to refer [android:windowSoftInputMode documents](http://developer.android.com/guide/topics/manifest/activity-element.html#wsoft) and try out different combinations.Then see if you can find your required combination. – Sash_KP Sep 04 '14 at 22:50
  • I don't have any inputmodes set in the manifest and I don't believe it will help because it controls how the softkeyboard reacts on entering the Activity. But my problem is the transition to another fragment. – Maniac Sep 05 '14 at 02:24

9 Answers9

12

I would to following things:

1. Extend Fragment class
2. Override onAttach() and onDetach() callbacks
3. Implement show and hide software keyboard method

sample code:

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);
   }
}
bpawlowski
  • 1,025
  • 2
  • 11
  • 22
3

I have the same problem with my app and finally we have 2 options, at first create a general function and call this in all transitions or create a global transition how this:

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

The best way is capture the transition event but we can't in this moment... Tell me if I helps you, good luck!

1

This will work for sure:

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);
   }
R.daneel.olivaw
  • 2,681
  • 21
  • 31
Rishabh Srivastava
  • 3,683
  • 2
  • 30
  • 58
0

I am guessing that your ListView is stealing the focus of your EditText, try this and let me know if it helps.

getListView().setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
Bojan Kseneman
  • 15,488
  • 2
  • 54
  • 59
0

Try this

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

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

I agree, I couldn't believe that you had to manually hide the keyboard as well.

Add this to your Fragment onCreate that you do not want the Keyboard not to be in:

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

change mToolbar to any view within the layout. In this case I used my toolbar.

Add this to the Fragment onCreate that you want the keyboard to be shown.

        ((InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE)).toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
Eugene H
  • 3,520
  • 3
  • 22
  • 39
0

you can use below code to hide soft keyboard.

InputMethodManager inputManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); 
inputManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(),InputMethodManager.HIDE_NOT_ALWAYS);
Durgesh
  • 291
  • 2
  • 19
0

for Kotlin :

  1. put this function in somewhere like Utils class.
fun hideSoftKeyboard(view: View, context: Context) {
        val inputMethodManager = 
            context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0)
    }

then use it in Fragments or Activities Like:


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

One way is to call Activity.recreate, since it is necessary to handle the orientation-change case anyway. Seems like overkill, and you also end up with different transition animations.

usethe4ce
  • 23,261
  • 4
  • 30
  • 30