Як відхилити DialogFragment при натисканні поза діалоговим вікном?


80

Я використовую a DialogFragment, і хоча я успішно встановив зображення, щоб закрити (тобто відхилити) діалогове вікно при натисканні, мені важко знайти спосіб закрити діалогове вікно, коли користувач клацає де-небудь поза ним, як це працює з звичайні діалоги. Я думав, що там буде щось таке

dialogFragment.setCanceledOnTouchOutside(true);

дзвоніть, але я не бачу цього в документації.

Чи можливо це DialogFragmentвзагалі? Або я шукаю не в тих місцях? Я спробував перехопити події дотику в "батьківській" діяльності, але окрім того, що я не отримав жодної події дотику, мені це здавалося не правильно.

Відповіді:


177
DialogFragment.getDialog().setCanceledOnTouchOutside(true);

Потрібно викликати onCreateView(як зазначив Апурв Гупта).


34
Потрібно викликатиonCreateView
Апурв Гупта

Що робити, якщо я не хочу, щоб його скасовували, а натомість просто закривали?
jjxtra

58
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
       ...
       getDialog().setCanceledOnTouchOutside(true);
       ... 
       }

у моєму випадку getDialog (). setCanceledOnTouchOutside (true); не сработало, сработало getDialog (). dismiss ();
Максим Фомичёв

@ МаксимФомичев, у першому випадку відбувається встановлення властивостей діалогу, що його можна закрити натисканням снаружи. У другому випадку ви самі програмуєте закрити діалог.
CoolMind

21
    /** The system calls this only when creating the layout in a dialog. */
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // The only reason you might override this method when using onCreateView() is
        // to modify any dialog characteristics. For example, the dialog includes a
        // title by default, but your custom layout might not need it. So here you can
        // remove the dialog title, but you must call the superclass to get the Dialog.
        Dialog dialog = super.onCreateDialog(savedInstanceState);
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setCanceledOnTouchOutside(true);

        return dialog;
    }

у мене це не спрацювало. Я повинен був дзвонити setCanceledOnTouchOutsideв onCreateViewвідповідно до @Apurv. Слід згадати, що я дзвонивsetCanceledOnTouchOutside(false)
kimbaudi

8

Тут безліч відповідей, але, програма аварійно завершує роботу при відкритті діалогового вікна. Писати getDialog().setCanceledOnTouchOutside(true);всередині onCreateViewне працювало, і мій додаток розбився.

(Я використовую AppCompatActivityяк свою BaseActivity та android.app.DialogFragmentяк мій фрагмент).

Що працює, це один із двох наступних рядків:

getDialog (). setCanceledOnTouchOutside (true);

АБО

this.getDialog (). setCanceledOnTouchOutside (true);

всередині onActivityCreatedподобається

@Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        //getDialog().getWindow().getAttributes().windowAnimations = R.style.DialogAnimationZoom;
        //getDialog().getWindow().setDimAmount(0.85f);
        getDialog().setCanceledOnTouchOutside(true);//See here is the code
    }

Що не можна використовувати:

DialogFragment.getDialog (). SetCanceledOnTouchOutside (false);

викидає наступну помилку

введіть тут опис зображення

І написання коду в програмі onCreateViewаварійно завершує роботу! Будь ласка, оновіть відповідь, якщо виявите щось не так.


Можливо, це тому, що ви створюєте всередині діалогове вікно onCreateDialog(), де це звичайний спосіб ініціалізації. У цьому випадку onCreateView()нічого не робить і навіть не містить подання. Можна спробувати перенести код onCreateDialog().
CoolMind

@CoolMind О, це приємне спостереження. Напевно збережу це в моєму списку спроб. Дякую!
sud007

Я думаю, ваша відповідь, тим не менше, дає сенс, і 4 людини відзначили плюси. Я також відчув проблеми з onCreateDialog, onCreateViewв недалекому минулому. Можливо, я помиляюся, і ви повинні зберегти onActivityCreated, це хороший метод зробити додаткову ініціалізацію (див. , Наприклад, stackoverflow.com/a/50734566/2914140 ).
CoolMind

@CoolMind приємно, що працює для вас. Але я можу помітити, що проблеми, які ви відчуваєте, пов'язані з вашим BottomSheetвпровадженням. У випадку BSheet я можу по-іншому погодитися. Але це рішення для a DialogFragmentпрацює добре.
sud007

3
DialogFragment.getDialog().setCanceledOnTouchOutside(false);

Це було неправильне друкування. У мене була та сама проблема. Це чудово працює для Java, а Mono для android Mono буде:

this.getDialog().SetCanceledOnTouchOutside(false);

Але хто щось запитував про Моно? : /
m0skit0

1
            Dialog.SetCanceledOnTouchOutside(true);

Працював для мене
Мій Кодекс

class dlgRegister : DialogFragment
        {
    public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
            {
    ....
    ....
    }
    public override void OnActivityCreated(Bundle savedInstanceState)
            {
                Dialog.Window.RequestFeature(WindowFeatures.NoTitle);
                Dialog.SetCanceledOnTouchOutside(true);
                base.OnActivityCreated(savedInstanceState);
                Dialog.Window.Attributes.WindowAnimations =    Resource.Style.dialog_animation;
            }
    }

1

Якщо ви хочете виконати певну логіку при натисканні за межами a DialogFragment, просто перевизначте метод onCancel.

override fun onCancel(dialog: DialogInterface) {
    super.onCancel(dialog)
    // Do your work here
}

0

Я б рекомендував використовувати своє рішення лише після випробування вищезазначених рішень. Я описав своє рішення тут . Щоб коротко сказати, я перевіряю межі дотику DialogFragment.getView (). Коли точки дотику знаходяться поза DialogFragment, я відкидаю діалог.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.