1
votes

Comment empêcher un DialogFragment de disparaître au toucher à l'extérieur?

J'utilise un DialogFragment qui affichera une vue entièrement personnalisée, aucun bouton natif utilisé. J'ai défini le dialogue annulable avec dialog.SetCanceledOnTouchOutside (true); Et lorsque l'utilisateur touche à l'extérieur, je souhaite exécuter du code pour déterminer si la boîte de dialogue doit être fermée ou non. Mon problème est que lorsqu'un événement est déclenché (annulé, ignoré), la boîte de dialogue est déjà fermée avant même la super.Dismiss (); donc je ne peux jamais contourner le rejet.

J'ai essayé beaucoup de choses, outrepasser les OnDismiss et OnCancel du fragment (déclenché mais trop tard), définir les écouteurs sur le dialogBuilder ET / OU sur le dialogue lui-même (pas déclenché ou trop tard ), remplacez OnShow pour réinitialiser les écouteurs etc ...

Rester coincé avec ça, une idée?

PS: Utilisation de Xamarin

public override Dialog OnCreateDialog(Bundle savedInstanceState)
{
    AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this.Activity);
    alertDialogBuilder.SetView(myView);
    AlertDialog dialog = alertDialogBuilder.Create();
    dialog.SetCanceledOnTouchOutside(true);
    return dialog;
}

public override void OnDismiss(IDialogInterface dialog)
{
    //BreakPoint here, already dismissed
    base.OnDismiss(dialog);
}


9 commentaires

vous avez appelé dialog.SetCanceledOnTouchOutside (true); et vous voulez empêcher un DialogFragment de se fermer au toucher à l'extérieur ... Sérieusement, que devez-vous accomplir?


Je souhaite autoriser l'annulation sur TouchOutside, mais je peux l'interrompre


Dans onCreateDialog lui-même, configurez dialog.setOnDismissListener et essayez


Déjà essayé, OnDismissListener n'est même pas déclenché avec alertDialogBuilder.SetOnDismissListener (new OnDialogDismissListener ()) ni dialog.SetOnDismissListener (new OnDialogDismissListener ())


En fait, la seule façon de déclencher OnDialogDismissListener est de dialog.SetOnShowListener et dans l'événement OnShow, définissez alertDialog.SetOnDismissListener (new OnDialogDismissListener ()); Mais même là ça se lève trop tard ...


fermez simplement le fragment uniquement via un bouton d'annulation. faites vos affaires en cliquant sur le bouton d'annulation


Merci mais ce n'est pas ce que je veux


Vous pouvez essayer de définir dialog.SetCanceledOnTouchOutside (false); sur false, vous pouvez empêcher le DialogFragment de se fermer au toucher à l'extérieur.


Oui, mais je souhaite autoriser l'annulation à l'extérieur


4 Réponses :


0
votes

Cela devrait être appelé sur le onCreateView()

DialogFragment.getDialog().setCanceledOnTouchOutside(true);


0 commentaires

1
votes

La solution que j'ai trouvée est:

fermez simplement le fragment uniquement via un bouton d'annulation. fais tes affaires Annuler le clic sur le bouton

dialog.Cancelable = false;

_cancelButton =dialog.FindViewById(Resource.Id.btnOptionOne );

_cancelButton.Click += CancelButtonPositiveButtonClick;

private void CancelButtonPositiveButtonClick (object sender, EventArgs e) {
    //do something here and dismiss the dialog if you want to:
    if (satisfied) {
        DismissDialog();
    }
}
private void DismissDialog () {
    _cancelButton.Click -= CancelButtonPositiveButtonClick;
    dialog.Dismiss ();
}


3 commentaires

Je veux pouvoir annuler, mais je veux pouvoir interrompre l'annulation à partir du code


fermez simplement le fragment uniquement via un bouton d'annulation. faites vos affaires en cliquant sur le bouton d'annulation


Je ne veux pas de bouton d'annulation



2
votes

Voulez-vous obtenir ce résultat? Si vous cliquez à l'extérieur de la boîte de dialogue, nous pouvons détecter l'événement de clic avant la fermeture de la boîte de dialogue. entrez la description de l'image ici

Vous pouvez créer un MyAlertDialog hériter du AlertDialog

private void BtnClick_Click(object sender, System.EventArgs e)
    {
        MyDialog dialog = new MyDialog();
        dialog.Show(SupportFragmentManager, "dialog");
    }

La partie suivante est DialogFragment.

    public class MyDialog:Android.Support.V4.App.DialogFragment
{

    public override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);

    }


    public override Dialog OnCreateDialog(Bundle savedInstanceState)
    {


        MyAlertDialog alertDialogBuilder = new MyAlertDialog(this.Activity);
        alertDialogBuilder.SetTitle("MyDialog");
        alertDialogBuilder.SetCanceledOnTouchOutside(true);
        return alertDialogBuilder;
    }



    public override void OnPause()
    {
        base.OnPause();
    }

    public override void OnCancel(IDialogInterface dialog)
    {
        base.OnCancel(dialog);
    }

    public override void OnDismiss(IDialogInterface dialog)
    {
        base.OnDismiss(dialog);
    }
}

Cliquez sur le bouton pour pousser la boîte de dialogue.

    public class MyAlertDialog:AlertDialog
{
    public MyAlertDialog(Context c):base(c) {

    }

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        //Please add following code for watching outside touch
        this.Window.SetFlags(WindowManagerFlags.NotTouchModal, WindowManagerFlags.NotTouchModal);
        this.Window.AddFlags(WindowManagerFlags.WatchOutsideTouch);
    }



    public override bool OnTouchEvent(MotionEvent e)
    {
        //just used for testing.
        var sss = "test";
        //If you want to close the Dialog when click the outside the Dialog part.
        //this.Dismiss();
        return true;
    }

}


2 commentaires

C'est exactement mon objectif, je vais essayer cela dès que possible, merci!


Cela fonctionne comme un charme, j'y étais presque mais j'ai raté les drapeaux :(. Merci @LeonLuMsft



0
votes

Solution correcte si simple:

/**
 * Sets whether this dialog is canceled when touched outside the window's
 * bounds. If setting to true, the dialog is set to be cancelable if not
 * already set.
 * 
 * @param cancel Whether the dialog should be canceled when touched outside
 *            the window.
 */

De la documentation:

dialog?.setCanceledOnTouchOutside(false)


0 commentaires