2

I am working with fragments and nesting fragments within fragments using the support library.

I have a scenario where I add a new fragment (which contains an EditText) from within the existing fragment. When the user taps on the EditText a virtual keyboard is shown. But while the keyboard is open the user can press the home button from the ActionBar which removes the fragment from the stack, but the keyboard still remains open. I can not force a close on the keyboard, I tried all code snippets. Given the described scenario, can anyone guide me as to how can I solve this ?

EDIT: I made a callback function which I call from the fragments onDestroy. The MainActivity which hosts all fragments implements this callback:

@Override
public void onHideSoftKeyboard(EditText editText) {
    // HIDE SOFT KEYBOARD HERE 

final InputMethodManager imm = (InputMethodManager)this.getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);

     Toast.makeText(this,"KEYBOARD HIDDEN",Toast.LENGTH_LONG).show();
}

I get the Toast message and the fragment is destroyed on the back button (ActionBar back button), only the keyboard is still present.

@Override
public void onDestroy() {
    hideSoftKeyboard.onHideSoftKeyboard(editTextComment);



    super.onDestroy();
}
Speed Demon
  • 691
  • 1
  • 9
  • 21
  • Please check my answer [On this Stack overflow thread](http://stackoverflow.com/a/23934639/1773155). It was the only way that was useful for me. – Shajeel Afzal May 29 '14 at 13:37

4 Answers4

13

Try to force the keyboard with this:

InputMethodManager imm = (InputMethodManager)getSystemService(
  Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(myEditText.getWindowToken(), 0);  

You also can like this:

imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);  

If you want to hide when the user click on Up Home Button, try like this in your onOptionsItemSelected method:

case android.R.id.home:  
     // count the active fragment
     if(getSupportFragmentManager().getStackBackEntryCount() > 0) {
         // hide soft method as above
         InputMethodManager mImm = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE); 
         mImm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
         // do the pop backstack
         getSupportFragmentManager().popBackStack(); 
     } else {  
         // some stuff like finish the activity
     }
     return true;
// other items...

You can do the same with the back button when you use the (override) onBackPressed method.

Blo
  • 11,903
  • 5
  • 45
  • 99
  • I already tried putting this snippet (with the reference to my EditText) in the onDestroy of the fragment, but the keyboard is still there :( – Speed Demon Dec 23 '13 at 15:03
  • @SpeedDemon I edited my answer, I used this snippet in my FragmentActivity and works well with the fragments and backstack method. – Blo Dec 23 '13 at 15:18
  • ok thank you, I will have to play around with this one and will see what happens – Speed Demon Dec 23 '13 at 15:28
  • I can hide the keyboard from a button click inside the fragment, but I can't detect the ActionBar home button click (which from this fragment behaves like up carrot). I am doing the switch case in onOptionsItemSelected with case android.R.id.home: but nothing ..it just removes the fragment from the stack but doesn't execute a line i put there.I am really confused – Speed Demon Dec 24 '13 at 08:19
  • It seems to work if you put the keyboard-closing code in onStop rather than onDestroy of the fragment. In onDestroy getWindowToken returns null, but not in onStop. – Andrew Fleenor May 13 '14 at 03:58
1

You can use following code.

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    final InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(getView().getWindowToken(), 0);
}
Hardik Joshi
  • 9,477
  • 12
  • 61
  • 113
1

I've fixed this issue with the following. First, if you want to pop the keyboard automatically when the activity launches, write the code below in the onCreate method.

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);

Then, if you want to close the keyboard, use the following.

InputMethodManager imm = (InputMethodManager)  getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY,0);
Pang
  • 9,564
  • 146
  • 81
  • 122
Kirubel
  • 1,461
  • 1
  • 14
  • 33
0

I solved this issue with the next solution

You need extend every your Fragment from BaseFragment as below:

public class BaseFragment extends Fragment {

    @Override
    public void onDestroyView() {
        hideKeyboard(getView());
        super.onDestroyView();
    }

    public void hideKeyboard(View view) {
        if(view != null) {
            InputMethodManager imm = (InputMethodManager) getContext()
                    .getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
        }
    }
}

And all fragments that you want to be hide the keyboard when it will closed, must extend BaseFragment:

public class EditTextFragment extends BaseFragment {
...
}

As a bonus in every extended fragment you can use hideKeyboard(View view) method to hide keyboard when you want in any place in your fragment

Trancer
  • 765
  • 2
  • 8
  • 23