How to hide the onscreen keyboard when a DialogFragment is canceled by the setCanceledOnTouchOutside event
Asked Answered
C

4

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.

Conative answered 29/4, 2013 at 0:9 Comment(1)
You need to override the onDismiss() method in your DialogFragment and hide the keyboard from there.Glantz
D
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.

Disjoined answered 5/5, 2014 at 16:27 Comment(3)
This gives the same issue, the cancel() is called, but the ime stays open.Venator
This is the only one that helped.Ibidem
Bravo! Note that hideSoftInputFromWindow() will still need to be issued elsewhere to cover normal DialogFragment termination.Verbenia
A
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();
}
Apodosis answered 7/3, 2014 at 16:59 Comment(3)
I have the same problem with the ime, this didn't work for me :(Venator
This worked consistently for me. Thanks. Though I don't know what check you are doing with your Utilities class? What do you mean by isValidActivity?Juryrigged
what is isValidActivity?Plano
V
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"
Venator answered 9/5, 2014 at 17:3 Comment(0)
F
0

Try adding an onDismissListener like this.

dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {

        @Override
        public void onDismiss(DialogInterface dialog) {
            // TODO Auto-generated method stub
            dismiss();
            }
        });
Favouritism answered 29/4, 2013 at 1:5 Comment(4)
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.Conative
Which view calls the keyboard? Instead of getView() use the actual widget calling the keyboard to dismiss it.Favouritism
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.Conative
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.Conative

© 2022 - 2024 — McMap. All rights reserved.