Как скрыть экранную клавиатуру, когда DialogFragment отменяется событием setCanceledOnTouchOutside

Если edittext в настоящее время сфокусирован, и пользователь щелкает за пределами диалогового окна; Я хочу, чтобы экранная клавиатура исчезла. Я могу заставить его работать, когда DialogFragment отклоняется следующим образом:

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

Однако, если я попытаюсь сделать то же самое, когда его отменит, коснувшись внешнего диалога, он не будет работать. Я пытаюсь сделать это, переопределив onCancel следующим образом:

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

Функция вызывается, когда происходит событие внешнего касания, но клавиатура не удаляется.

Ответ 1

Это то, что я сделал, чтобы это наконец-то помогло... Мне не нужно было использовать виджет для клавиатуры... но использовать currentfocus, чтобы заставить windowtoken удалить клавиатуру, когда пользователь выбрал что-то вне диалога...

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

Ответ 2

Мне удалось решить ту же проблему, подклассифицируя диалог и скрывая клавиатуру до того, как был выполнен код отмены в диалоговом окне.

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

Я пробовал много альтернативных подходов, в том числе с помощью прослушивателей DialogFragment onCancel и onDimiss. Я считаю, что проблема заключается в том, что слушатели называются асинхронно, в то время как увольнение/отмена обрабатываются синхронно; поэтому к тому времени, когда ваш слушатель вызывается, чтобы скрыть клавиатуру, токен окна больше не существует.

Ответ 3

У меня была такая же проблема, и я решил ее, поместив ее в AndroidManifest под действие, в котором я порожу DialogFragment:

android:windowSoftInputMode="stateHidden"

Ответ 4

Попробуйте добавить onDismissListener, как это.

dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {

        @Override
        public void onDismiss(DialogInterface dialog) {
            // TODO Auto-generated method stub
            dismiss();
            }
        });