10

If an edittext is currently focused and the user clicks outside of the DialogFragment; I want the on screen keyboard to disappear. I can get it to work for when the DialogFragment is dismissed this way:

InputMethodManager imm;
public View onCreateView(LayoutInflater inflator, ViewGroup container,
        Bundle savedInstanceState) {
imm = (InputMethodManager)getActivity().getSystemService(Activity.INPUT_METHOD_SERVICE);
...}

@Override 
public void dismiss(){
    imm.hideSoftInputFromWindow(getView().getWindowToken(), 0);
    super.dismiss();
}

However, if I try the same thing for when it is canceled by touching outside of the dialogfragment, it will not work. I am trying to do this by overriding onCancel like so:

@Override
public void onCancel(DialogInterface dialog){
    imm.hideSoftInputFromWindow(getView().getWindowToken(), 0);
    super.onCancel(dialog);
}

The function is called when the outside touch event happens, but the keyboard is not removed.

JaRay
  • 164
  • 1
  • 9
  • You need to override the `onDismiss()` method in your `DialogFragment` and hide the keyboard from there. – Clans Jun 19 '13 at 08:28

4 Answers4

5

I was able to solve the same problem by sub-classing the dialog and hiding the keyboard before the cancel code on the dialog was executed.

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    Dialog dialog = new Dialog(getActivity(), getTheme()) {
        @Override public void cancel() {
            if (getActivity() != null && getView() != null) {
                InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(getView().getWindowToken(), 0);
            }
            super.cancel();
        }

    };
    return dialog;
}

I tried many alternate approaches including using the DialogFragment's onCancel and onDimiss listeners to no avail. I believe the issue is that the listeners are called asynchronously while the dismiss/cancel is handled synchronously; so by the time your listener is called to hide the keyboard, the window token no longer exists.

k3v
  • 1,189
  • 12
  • 12
1

This is what I did to get this to finally work... I needed to not use the widget for the keyboard... but use the currentfocus to get the windowtoken to remove the keyboard when a user selected something outside the dialog...

@Override
public void onStop() {
    // make sure the keyboard goes away when the user selects something outside the view (cancelled outside)
    if( Utilities.isValidActivity(this.getActivity())) {
        InputMethodManager imm = (InputMethodManager)this.getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
        // not the search view but the current focus at this point
        imm.hideSoftInputFromWindow(this.getActivity().getCurrentFocus().getWindowToken(), 0);                          
    }
    super.onStop();
}
lepert
  • 515
  • 6
  • 8
1

I had the same issue and solved it by putting this in the AndroidManifest under the activity where I spawn the DialogFragment:

android:windowSoftInputMode="stateHidden"
Eduard
  • 3,482
  • 2
  • 27
  • 45
0

Try adding an onDismissListener like this.

dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {

        @Override
        public void onDismiss(DialogInterface dialog) {
            // TODO Auto-generated method stub
            dismiss();
            }
        });
Karthik Balakrishnan
  • 4,353
  • 6
  • 37
  • 69
  • I like the idea of this, but it does not work. In fact, if the DialogFragment is dismissed by the touch outside event, the OnDissmissListener is ignored. I know onCancel is called when the touch outside event happens, but hideSoftInputFromWindow does not do anything in this situation. – JaRay Apr 29 '13 at 14:28
  • Which view calls the keyboard? Instead of `getView()` use the actual widget calling the keyboard to dismiss it. – Karthik Balakrishnan Apr 29 '13 at 14:40
  • I wasn't using the actual widget because their are multiple edittext widgets available on the screen. However, I chose one to try out your suggestion, and it still does not work. – JaRay Apr 30 '13 at 15:31
  • 1
    In fact, the onDismissListener is skipped altogether. Here is what I added inside of onCreateView of the DialogFragment: this.getDialog().setOnDismissListener(new DialogInterface.OnDismissListener(){ @Override public void onDismiss(DialogInterface arg0){ dismiss(); } }); This listener is not called when the setCanceledOnTouchOutside even happens. – JaRay Apr 30 '13 at 15:40