Jak odrzucić DialogFragment po naciśnięciu poza oknem dialogowym?

80

Używam DialogFragmenti chociaż pomyślnie ustawiłem obraz, aby zamknąć (tj. Zamknąć) okno dialogowe po naciśnięciu, trudno mi znaleźć sposób na zamknięcie okna dialogowego, gdy użytkownik kliknie gdziekolwiek poza nim, tak jak działa z normalne okna dialogowe. Myślałem, że będzie coś takiego

dialogFragment.setCanceledOnTouchOutside(true);

zadzwonić, ale nie widzę tego w dokumentacji.

Czy to DialogFragmentw ogóle możliwe ? A może szukam w złych miejscach? Próbowałem przechwytywać zdarzenia dotykowe w aktywności „rodzica”, ale poza tym, że nie otrzymywałem żadnego zdarzenia dotykowego, nie wydawało mi się to właściwe.

podeszwa
źródło

Odpowiedzi:

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

Trzeba wezwać onCreateView(jak zauważył Apurv Gupta).

Hamed
źródło
34
Należy wezwaćonCreateView
Apurv Gupta
A co, jeśli nie chcę, aby anulować, ale po prostu zamknąć?
jjxtra
58
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
       ...
       getDialog().setCanceledOnTouchOutside(true);
       ... 
       }
manuzhang
źródło
в моем случае 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;
    }
Yakiv Mospan
źródło
to nie zadziałało dla mnie. Musiałem zadzwonić setCanceledOnTouchOutsidew onCreateViewzgodnie @Apurv. Powinienem wspomnieć, że setCanceledOnTouchOutside(false)
dzwoniłem
8

Wiele odpowiedzi tutaj, ale aplikacja ulega awarii po otwarciu okna dialogowego. Pisanie w getDialog().setCanceledOnTouchOutside(true);środku onCreateViewnie działało i spowodowało awarię mojej aplikacji.

(Używam AppCompatActivityjako mojej BaseActivity i android.app.DialogFragmentjako mojego fragmentu).

To, co działa, to jeden z dwóch następujących wierszy:

getDialog (). setCanceledOnTouchOutside (true);

LUB

this.getDialog (). setCanceledOnTouchOutside (true);

wewnątrz onActivityCreatedjak

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

Czego nie używać:

DialogFragment.getDialog (). SetCanceledOnTouchOutside (false);

zgłasza następujący błąd

wprowadź opis obrazu tutaj

A napisanie kodu w onCreateViewaplikacji wywala! Zaktualizuj odpowiedź, jeśli znajdziesz coś nie tak.

sud007
źródło
Prawdopodobnie dzieje się tak, ponieważ tworzysz okno dialogowe w środku onCreateDialog(), w którym jest to zwykły sposób inicjalizacji. W tym przypadku onCreateView()nic nie robi, a nawet nie zawiera widoku. Możesz spróbować przenieść kod do onCreateDialog().
CoolMind
@CoolMind Och, to miła obserwacja. Na pewno zatrzymam to na mojej liście prób. Dzięki!
sud007
Myślę, że jednak twoja odpowiedź ma sens, a 4 osoby zaznaczyły plusy. Ja też miały problemy z onCreateDialog, onCreateVieww niedalekiej przeszłości. Może się mylę i powinieneś zachować onActivityCreated, jest to fajna metoda na wykonanie dodatkowej inicjalizacji (patrz na przykład stackoverflow.com/a/50734566/2914140 ).
CoolMind
@CoolMind fajnie, że działa dla Ciebie. Ale mogę zauważyć, że problemy, których doświadczasz, są spowodowane twoją BottomSheetimplementacją. Może być inaczej w przypadku BSheet Zgadzam się. Ale to rozwiązanie DialogFragmentdziała dobrze.
sud007
3
DialogFragment.getDialog().setCanceledOnTouchOutside(false);

To było błędne. Miałem ten sam problem. Działa to dobrze dla Java i Mono dla Androida Mono będzie:

this.getDialog().SetCanceledOnTouchOutside(false);
Eugene Bosikov
źródło
Ale kto pytał o Mono? : /
m0skit0
1
            Dialog.SetCanceledOnTouchOutside(true);

Pracował dla mnie
mój kod

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;
            }
    }
pozorny
źródło
1

Jeśli chcesz wykonać jakąś logikę po kliknięciu poza a DialogFragment, po prostu zastąp metodę onCancel.

override fun onCancel(dialog: DialogInterface) {
    super.onCancel(dialog)
    // Do your work here
}
Tomasz
źródło
0

Poleciłbym skorzystać z mojego rozwiązania dopiero po wypróbowaniu powyższych rozwiązań. Tutaj opisałem swoje rozwiązanie . Krótko mówiąc, sprawdzam granice dotykowe DialogFragment.getView (). Kiedy punkty dotykowe znajdują się poza DialogFragment, odrzucam okno dialogowe.

Swaroop
źródło