Question Comment empêcher une boîte de dialogue de se fermer lorsqu'un bouton est cliqué


J'ai un dialogue avec EditText pour l'entrée. Lorsque je clique sur le bouton "oui" dans la boîte de dialogue, l'entrée est validée puis fermée. Cependant, si l'entrée est incorrecte, je veux rester dans le même dialogue. Chaque fois que l'entrée est active, la boîte de dialogue doit être automatiquement fermée lorsque je clique sur le bouton "non". Comment puis-je désactiver cela? Par ailleurs, j'ai utilisé PositiveButton et NegativeButton pour le bouton sur la boîte de dialogue.


608
2018-04-12 07:18


origine


Réponses:


MODIFIER: Cela ne fonctionne que sur API 8+ comme indiqué par certains des commentaires.

C'est une réponse tardive, mais vous pouvez ajouter un onShowListener à AlertDialog où vous pouvez ensuite remplacer le onClickListener du bouton.

final AlertDialog dialog = new AlertDialog.Builder(context)
        .setView(v)
        .setTitle(R.string.my_title)
        .setPositiveButton(android.R.string.ok, null) //Set to null. We override the onclick
        .setNegativeButton(android.R.string.cancel, null)
        .create();

dialog.setOnShowListener(new DialogInterface.OnShowListener() {

    @Override
    public void onShow(DialogInterface dialogInterface) {

        Button button = ((AlertDialog) dialog).getButton(AlertDialog.BUTTON_POSITIVE);
        button.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                // TODO Do something

                //Dismiss once everything is OK.
                dialog.dismiss();
            }
        });
    }
});
dialog.show();

789
2017-10-03 14:34



Voici quelques solutions pour tous les types de dialogues, y compris une solution pour AlertDialog.Builder qui fonctionnera sur tous les niveaux de l'API (fonctionne en dessous de l'API 8, ce que l'autre ne répond pas ici). Il existe des solutions pour AlertDialogs utilisant AlertDialog.Builder, DialogFragment et DialogPreference.

Vous trouverez ci-dessous des exemples de code montrant comment remplacer le gestionnaire de boutons commun par défaut et empêcher la fermeture de la boîte de dialogue pour ces différentes formes de boîtes de dialogue. Tous les exemples montrent comment empêcher le bouton positif de fermer le dialogue.

Remarque: Une description de la façon dont la fermeture de la boîte de dialogue fonctionne sous le capot pour les classes android de base et pourquoi les approches suivantes sont choisies suit après les exemples, pour ceux qui veulent plus de détails


AlertDialog.Builder - Modifier le gestionnaire de boutons par défaut immédiatement après show ()

AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage("Test for preventing dialog close");
builder.setPositiveButton("Test", 
        new DialogInterface.OnClickListener()
        {
            @Override
            public void onClick(DialogInterface dialog, int which)
            {
                //Do nothing here because we override this button later to change the close behaviour. 
                //However, we still need this because on older versions of Android unless we 
                //pass a handler the button doesn't get instantiated
            }
        });
final AlertDialog dialog = builder.create();
dialog.show();
//Overriding the handler immediately after show is probably a better approach than OnShowListener as described below
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener()
      {            
          @Override
          public void onClick(View v)
          {
              Boolean wantToCloseDialog = false;
              //Do stuff, possibly set wantToCloseDialog to true then...
              if(wantToCloseDialog)
                  dialog.dismiss();
              //else dialog stays open. Make sure you have an obvious way to close the dialog especially if you set cancellable to false.
          }
      });

DialogFragment - override onResume ()

@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    builder.setMessage("Test for preventing dialog close");
    builder.setPositiveButton("Test", 
        new DialogInterface.OnClickListener()
        {
            @Override
            public void onClick(DialogInterface dialog, int which)
            {
                //Do nothing here because we override this button later to change the close behaviour. 
                //However, we still need this because on older versions of Android unless we 
                //pass a handler the button doesn't get instantiated
            }
        });
    return builder.create();
}

//onStart() is where dialog.show() is actually called on 
//the underlying dialog, so we have to do it there or 
//later in the lifecycle.
//Doing it in onResume() makes sure that even if there is a config change 
//environment that skips onStart then the dialog will still be functioning
//properly after a rotation.
@Override
public void onResume()
{
    super.onResume();    
    final AlertDialog d = (AlertDialog)getDialog();
    if(d != null)
    {
        Button positiveButton = (Button) d.getButton(Dialog.BUTTON_POSITIVE);
        positiveButton.setOnClickListener(new View.OnClickListener()
                {
                    @Override
                    public void onClick(View v)
                    {
                        Boolean wantToCloseDialog = false;
                        //Do stuff, possibly set wantToCloseDialog to true then...
                        if(wantToCloseDialog)
                            d.dismiss();
                        //else dialog stays open. Make sure you have an obvious way to close the dialog especially if you set cancellable to false.
                    }
                });
    }
}

DialogPreference - override showDialog ()

@Override
protected void onPrepareDialogBuilder(Builder builder)
{
    super.onPrepareDialogBuilder(builder);
    builder.setPositiveButton("Test", this);   //Set the button here so it gets created
}

@Override
protected void showDialog(Bundle state)
{       
    super.showDialog(state);    //Call show on default first so we can override the handlers

    final AlertDialog d = (AlertDialog) getDialog();
    d.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener()
            {            
                @Override
                public void onClick(View v)
                {
                    Boolean wantToCloseDialog = false;
                    //Do stuff, possibly set wantToCloseDialog to true then...
                    if(wantToCloseDialog)
                        d.dismiss();
                    //else dialog stays open. Make sure you have an obvious way to close the dialog especially if you set cancellable to false.
                }
            });
}

Explication des approches:

En regardant à travers le code source Android, l'implémentation par défaut d'AlertDialog fonctionne en enregistrant un gestionnaire de boutons commun à tous les boutons réels dans OnCreate (). Quand un bouton est cliqué, le gestionnaire de bouton commun transmet l'événement click au gestionnaire que vous avez passé dans setButton (), puis appelle la boîte de dialogue.

Si vous souhaitez empêcher la fermeture d'une boîte de dialogue lorsque vous appuyez sur l'un de ces boutons, vous devez remplacer le gestionnaire de boutons commun pour l'affichage réel du bouton. Parce qu'il est affecté dans OnCreate (), vous devez le remplacer après que l'implémentation OnCreate () par défaut est appelée. OnCreate est appelé dans le processus de la méthode show (). Vous pouvez créer une classe Dialog personnalisée et remplacer OnCreate () pour appeler super.OnCreate (), puis remplacer les gestionnaires de boutons, mais si vous créez une boîte de dialogue personnalisée, vous ne recevez pas le Builder gratuitement, auquel cas, quel est le point? ?

Ainsi, en utilisant une boîte de dialogue comme elle est conçue mais avec contrôle quand elle est rejetée, une approche consiste à appeler dialog.Show () d'abord, puis obtenir une référence au bouton en utilisant dialog.getButton () pour surcharger le gestionnaire de clic. Une autre approche consiste à utiliser setOnShowListener () et à implémenter la recherche de la vue du bouton et le remplacement du gestionnaire dans OnShowListener. La différence fonctionnelle entre les deux est «presque» nulle, selon le thread qui crée à l'origine l'instance de dialogue. En parcourant le code source, onShowListener est appelé par un message posté sur un gestionnaire s'exécutant sur le thread qui a créé cette boîte de dialogue. Donc, puisque votre OnShowListener est appelé par un message posté dans la file d'attente des messages, il est techniquement possible que l'appel de votre écouteur soit retardé quelque temps après la fin du show.

Par conséquent, je crois que l'approche la plus sûre est la première: appeler show.Dialog (), puis immédiatement dans le même chemin d'exécution remplacer les gestionnaires de boutons. Puisque votre code qui appelle show () fonctionnera sur le thread principal de l'interface graphique, cela signifie que tout code que vous suivrez show () sera exécuté avant tout autre code sur ce thread, alors que le timing de la méthode OnShowListener est à la merci de la file d'attente de messages.


568
2018-03-25 15:48



J'ai écrit une classe simple (un AlertDialogBuilder) que vous pouvez utiliser pour désactiver la fonction de rejet automatique lorsque vous appuyez sur les boutons de la boîte de dialogue.

Il est également compatible avec Android 1.6, donc il n'utilise pas OnShowListener (qui est disponible uniquement API> = 8).

Ainsi, au lieu d'utiliser AlertDialog.Builder, vous pouvez utiliser ce CustomAlertDialogBuilder. La partie la plus importante est que vous ne devriez pas appeler créer()mais seulement le montrer() méthode. J'ai ajouté des méthodes comme setCanceledOnTouchOutside () et setOnDismissListener de sorte que vous pouvez toujours les définir directement sur le constructeur.

Je l'ai testé sur Android 1.6, 2.x, 3.x et 4.x donc ça devrait marcher plutôt bien. Si vous trouvez des problèmes, veuillez commenter ici.

package com.droidahead.lib.utils;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.view.View;
import android.view.View.OnClickListener;

public class CustomAlertDialogBuilder extends AlertDialog.Builder {
    /**
     * Click listeners
     */
    private DialogInterface.OnClickListener mPositiveButtonListener = null;
    private DialogInterface.OnClickListener mNegativeButtonListener = null;
    private DialogInterface.OnClickListener mNeutralButtonListener = null;

    /**
     * Buttons text
     */
    private CharSequence mPositiveButtonText = null;
    private CharSequence mNegativeButtonText = null;
    private CharSequence mNeutralButtonText = null;

    private DialogInterface.OnDismissListener mOnDismissListener = null;

    private Boolean mCancelOnTouchOutside = null;

    public CustomAlertDialogBuilder(Context context) {
        super(context);
    }

    public CustomAlertDialogBuilder setOnDismissListener (DialogInterface.OnDismissListener listener) {
        mOnDismissListener = listener;
        return this;
    }

    @Override
    public CustomAlertDialogBuilder setNegativeButton(CharSequence text, DialogInterface.OnClickListener listener) {
        mNegativeButtonListener = listener;
        mNegativeButtonText = text;
        return this;
    }

    @Override
    public CustomAlertDialogBuilder setNeutralButton(CharSequence text, DialogInterface.OnClickListener listener) {
        mNeutralButtonListener = listener;
        mNeutralButtonText = text;
        return this;
    }

    @Override
    public CustomAlertDialogBuilder setPositiveButton(CharSequence text, DialogInterface.OnClickListener listener) {
        mPositiveButtonListener = listener;
        mPositiveButtonText = text;
        return this;
    }

    @Override
    public CustomAlertDialogBuilder setNegativeButton(int textId, DialogInterface.OnClickListener listener) {
        setNegativeButton(getContext().getString(textId), listener);
        return this;
    }

    @Override
    public CustomAlertDialogBuilder setNeutralButton(int textId, DialogInterface.OnClickListener listener) {
        setNeutralButton(getContext().getString(textId), listener);
        return this;
    }

    @Override
    public CustomAlertDialogBuilder setPositiveButton(int textId, DialogInterface.OnClickListener listener) {
        setPositiveButton(getContext().getString(textId), listener);
        return this;
    }

    public CustomAlertDialogBuilder setCanceledOnTouchOutside (boolean cancelOnTouchOutside) {
        mCancelOnTouchOutside = cancelOnTouchOutside;
        return this;
    }



    @Override
    public AlertDialog create() {
        throw new UnsupportedOperationException("CustomAlertDialogBuilder.create(): use show() instead..");
    }

    @Override
    public AlertDialog show() {
        final AlertDialog alertDialog = super.create();

        DialogInterface.OnClickListener emptyOnClickListener = new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) { }
        };


        // Enable buttons (needed for Android 1.6) - otherwise later getButton() returns null
        if (mPositiveButtonText != null) {
            alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, mPositiveButtonText, emptyOnClickListener);
        }

        if (mNegativeButtonText != null) {
            alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, mNegativeButtonText, emptyOnClickListener);
        }

        if (mNeutralButtonText != null) {
            alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, mNeutralButtonText, emptyOnClickListener);
        }

        // Set OnDismissListener if available
        if (mOnDismissListener != null) {
            alertDialog.setOnDismissListener(mOnDismissListener);
        }

        if (mCancelOnTouchOutside != null) {
            alertDialog.setCanceledOnTouchOutside(mCancelOnTouchOutside);
        }

        alertDialog.show();

        // Set the OnClickListener directly on the Button object, avoiding the auto-dismiss feature
        // IMPORTANT: this must be after alert.show(), otherwise the button doesn't exist..
        // If the listeners are null don't do anything so that they will still dismiss the dialog when clicked
        if (mPositiveButtonListener != null) {
            alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    mPositiveButtonListener.onClick(alertDialog, AlertDialog.BUTTON_POSITIVE);
                }
            });
        }

        if (mNegativeButtonListener != null) {
            alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    mNegativeButtonListener.onClick(alertDialog, AlertDialog.BUTTON_NEGATIVE);
                }
            });
        }

        if (mNeutralButtonListener != null) {
            alertDialog.getButton(AlertDialog.BUTTON_NEUTRAL).setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    mNeutralButtonListener.onClick(alertDialog, AlertDialog.BUTTON_NEUTRAL);
                }
            });
        }

        return alertDialog;
    }   
}

MODIFIER Voici un petit exemple sur la façon d'utiliser le CustomAlertDialogBuilder:

// Create the CustomAlertDialogBuilder
CustomAlertDialogBuilder dialogBuilder = new CustomAlertDialogBuilder(context);

// Set the usual data, as you would do with AlertDialog.Builder
dialogBuilder.setIcon(R.drawable.icon);
dialogBuilder.setTitle("Dialog title");
dialogBuilder.setMessage("Some text..");

// Set your buttons OnClickListeners
dialogBuilder.setPositiveButton ("Button 1", new DialogInterface.OnClickListener() {
    public void onClick (DialogInterface dialog, int which) {
        // Do something...

        // Dialog will not dismiss when the button is clicked
        // call dialog.dismiss() to actually dismiss it.
    }
});

// By passing null as the OnClickListener the dialog will dismiss when the button is clicked.               
dialogBuilder.setNegativeButton ("Close", null);

// Set the OnDismissListener (if you need it)       
dialogBuilder.setOnDismissListener(new DialogInterface.OnDismissListener() {
    public void onDismiss(DialogInterface dialog) {
        // dialog was just dismissed..
    }
});

// (optional) set whether to dismiss dialog when touching outside
dialogBuilder.setCanceledOnTouchOutside(false);

// Show the dialog
dialogBuilder.show();

À votre santé,

Yuvi


31
2018-03-01 20:09



Voici quelque chose si vous utilisez DialogFragment - Quelle est la méthode recommandée pour gérer les dialogues de toute façon.

Qu'est-ce qui se passe avec AlertDialog setButton() méthode (et j'imagine la même chose avec AlertDialogBuilderde setPositiveButton() et setNegativeButton()) est le bouton que vous avez défini (par ex. AlertDialog.BUTTON_POSITIVE) avec elle va effectivement déclencher deux différents OnClickListener Objets lorsqu'il est pressé.

Le premier être DialogInterface.OnClickListener, qui est un paramètre à setButton(), setPositiveButton(), et setNegativeButton().

L'autre est View.OnClickListener, qui sera réglé pour rejeter automatiquement votre AlertDialog lorsque l'un de ses boutons est pressé - et est réglé par AlertDialog lui-même.

Ce que vous pouvez faire est d'utiliser setButton() avec null comme le DialogInterface.OnClickListener, pour créer le bouton, puis appelez votre méthode d'action personnalisée à l'intérieur View.OnClickListener. Par exemple,

@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
    AlertDialog alertDialog = new AlertDialog(getActivity());
    // set more items...
    alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "OK", null);

    return alertDialog;
}

Ensuite, vous pouvez remplacer la valeur par défaut AlertDialog'boutons' View.OnClickListener (qui autrement rejetterait le dialogue) dans le DialogFragmentde onResume() méthode:

@Override
public void onResume()
{
    super.onResume();
    AlertDialog alertDialog = (AlertDialog) getDialog();
    Button okButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
    okButton.setOnClickListener(new View.OnClickListener() { 
        @Override
        public void onClick(View v)
        {
            performOkButtonAction();
        }
    });
}

private void performOkButtonAction() {
    // Do your stuff here
}

Vous devrez définir ceci dans le onResume() méthode parce que getButton() reviendra null jusqu'à ce que le dialogue soit affiché!

Cela devrait provoquer l'appel de votre méthode d'action personnalisée une seule fois et la boîte de dialogue ne sera pas ignorée par défaut.


25
2018-05-19 00:17



Une solution alternative

Je voudrais présenter une réponse alternative à partir d'une perspective UX.

Pourquoi voudriez-vous empêcher la fermeture d'une boîte de dialogue lorsqu'un bouton est cliqué? Vraisemblablement, c'est parce que vous avez une boîte de dialogue personnalisée dans laquelle l'utilisateur n'a pas fait un choix ou n'a pas encore tout rempli. Et si elles ne sont pas terminées, vous ne devriez pas leur permettre de cliquer sur le bouton positif du tout. Désactivez-le jusqu'à ce que tout soit prêt.

Les autres réponses ici donnent beaucoup de trucs pour passer outre le clic positif. Si cela était important à faire, Android n'aurait-il pas fait une méthode pratique pour le faire? Ils n'ont pas.

Au lieu de cela, Guide de conception des dialogues montre un exemple d'une telle situation. Le bouton OK est désactivé jusqu'à ce que l'utilisateur fasse un choix. Aucune tromperie n'est nécessaire du tout. Il est évident pour l'utilisateur que quelque chose doit encore être fait avant de continuer.

enter image description here

Comment désactiver le bouton positif

Voir le Documentation Android pour la création d'une disposition de dialogue personnalisée. Il vous recommande de placer votre AlertDialog à l'intérieur DialogFragment. Ensuite, tout ce que vous devez faire est de définir les écouteurs sur les éléments de la mise en page pour savoir quand activer ou désactiver le bouton positif.

Le bouton positif peut être désactivé comme ceci:

AlertDialog dialog = (AlertDialog) getDialog();
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);

Voici un travail complet DialogFragment avec un bouton positif désactivé tel que celui utilisé dans l'image ci-dessus.

import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;

public class MyDialogFragment extends DialogFragment {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {

        // inflate the custom dialog layout
        LayoutInflater inflater = getActivity().getLayoutInflater();
        View view = inflater.inflate(R.layout.my_dialog_layout, null);

        // add a listener to the radio buttons
        RadioGroup radioGroup = (RadioGroup) view.findViewById(R.id.radio_group);
        radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup radioGroup, int i) {
                // enable the positive button after a choice has been made
                AlertDialog dialog = (AlertDialog) getDialog();
                dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(true);
            }
        });

        // build the alert dialog
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setView(view)
                .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                        // TODO: use an interface to pass the user choice back to the activity
                    }
                })
                .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        MyDialogFragment.this.getDialog().cancel();
                    }
                });
        return builder.create();
    }

    @Override
    public void onResume() {
        super.onResume();

        // disable positive button by default
        AlertDialog dialog = (AlertDialog) getDialog();
        dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
    }
}

La boîte de dialogue personnalisée peut être exécutée à partir d'une activité comme celle-ci:

MyDialogFragment dialog = new MyDialogFragment();
dialog.show(getFragmentManager(), "MyTag");

Remarques

  • Par souci de brièveté, j'ai omis l'interface de communication pour renvoyer les informations de choix de l'utilisateur à l'activité. le Documentation montre comment cela est fait, cependant.
  • Le bouton est toujours null dans onCreateDialog donc je l'ai désactivé dans onResume. Cela a l'effet indésirable de le désactiver à nouveau si l'utilisateur passe à une autre application et revient ensuite sans fermer la boîte de dialogue. Cela pourrait être résolu en désélectionnant tout choix d'utilisateur ou en appelant un Runnable de onCreateDialog pour désactiver le bouton sur la prochaine boucle d'exécution.

    view.post(new Runnable() {
        @Override
        public void run() {
            AlertDialog dialog = (AlertDialog) getDialog();
            dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
        }
    });
    

en relation


19
2017-11-18 05:26



Inspiré par la réponse de Tom, je crois que l'idée ici est:

  • Met le onClickListener lors de la création du dialogue à null
  • Puis définissez un onClickListener après le dialogue est affiché.

Vous pouvez remplacer le onShowListener comme Tom. Alternativement, vous pouvez

  1. obtenir le bouton après avoir appelé AlertDialog show()
  2. régler les boutons onClickListener comme suit (un peu plus lisible je pense).

Code:

AlertDialog.Builder builder = new AlertDialog.Builder(context);
// ...
final AlertDialog dialog = builder.create();
dialog.show();
// now you can override the default onClickListener
Button b = dialog.getButton(AlertDialog.BUTTON_POSITIVE);
b.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Log.i(TAG, "ok button is clicked");
        handleClick(dialog);
    }
});

16
2017-11-05 03:52



Pour la pré API 8, j'ai résolu le problème en utilisant un indicateur booléen, un écouteur de rejet et une boîte de dialogue d'appel.Rappelez de nouveau si au cas où le contenu de editText ne serait pas correct. Comme ça:

case ADD_CLIENT:
        LayoutInflater factoryClient = LayoutInflater.from(this);
        final View EntryViewClient = factoryClient.inflate(
                R.layout.alert_dialog_add_client, null);

        EditText ClientText = (EditText) EntryViewClient
                .findViewById(R.id.client_edit);

        AlertDialog.Builder builderClient = new AlertDialog.Builder(this);
        builderClient
                .setTitle(R.string.alert_dialog_client)
                .setCancelable(false)
                .setView(EntryViewClient)
                .setPositiveButton("Save",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog,
                                    int whichButton) {
                                EditText newClient = (EditText) EntryViewClient
                                        .findViewById(R.id.client_edit);
                                String newClientString = newClient
                                        .getText().toString();
                                if (checkForEmptyFields(newClientString)) {
                                    //If field is empty show toast and set error flag to true;
                                    Toast.makeText(getApplicationContext(),
                                            "Fields cant be empty",
                                            Toast.LENGTH_SHORT).show();
                                    add_client_error = true;
                                } else {
                                    //Here save the info and set the error flag to false
                                    add_client_error = false;
                                }
                            }
                        })
                .setNegativeButton("Cancel",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog,
                                    int id) {
                                add_client_error = false;
                                dialog.cancel();
                            }
                        });
        final AlertDialog alertClient = builderClient.create();
        alertClient.show();

        alertClient
                .setOnDismissListener(new DialogInterface.OnDismissListener() {

                    @Override
                    public void onDismiss(DialogInterface dialog) {
                        //If the error flag was set to true then show the dialog again
                        if (add_client_error == true) {
                            alertClient.show();
                        } else {
                            return;
                        }

                    }
                });
        return true;

8
2018-05-12 11:06



La réponse à ce lien est une solution simple, et qui est compatible avec l'API 3. Il est très similaire à la solution de Tom Bollwitt, mais sans utiliser le OnShowListener moins compatible.

Oui, vous pouvez. Vous devez essentiellement:

  1. Créer le dialogue avec DialogBuilder
  2. show () le dialogue
  3. Trouvez les boutons dans la boîte de dialogue affichée et remplacez leur onClickListener

J'ai fait des adaptations mineures au code de Kamen puisque j'étendais un EditTextPreference.

@Override
protected void showDialog(Bundle state) {
  super.showDialog(state);

  class mocl implements OnClickListener{
    private final AlertDialog dialog;
    public mocl(AlertDialog dialog) {
          this.dialog = dialog;
      }
    @Override
    public void onClick(View v) {

        //checks if EditText is empty, and if so tells the user via Toast
        //otherwise it closes dialog and calls the EditTextPreference's onClick
        //method to let it know that the button has been pressed

        if (!IntPreference.this.getEditText().getText().toString().equals("")){
        dialog.dismiss();
        IntPreference.this.onClick(dialog,DialogInterface.BUTTON_POSITIVE);
        }
        else {
            Toast t = Toast.makeText(getContext(), "Enter a number!", Toast.LENGTH_SHORT);
            t.show();
        }

    }
  }

  AlertDialog d = (AlertDialog) getDialog();
  Button b = d.getButton(DialogInterface.BUTTON_POSITIVE);
  b.setOnClickListener(new mocl((d)));
}

Si amusant!


6
2017-07-10 19:22



Ce code fonctionnera pour vous, parce que j'ai eu un problème simmilar et cela a fonctionné pour moi. :)

1- Remplacer la méthode Onstart () dans votre classe fragment-dialog.

@Override
public void onStart() {
    super.onStart();
    final AlertDialog D = (AlertDialog) getDialog();
    if (D != null) {
        Button positive = (Button) D.getButton(Dialog.BUTTON_POSITIVE);
        positive.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                if (edittext.equals("")) {
   Toast.makeText(getActivity(), "EditText empty",Toast.LENGTH_SHORT).show();
                } else {
                D.dismiss(); //dissmiss dialog
                }
            }
        });
    }
}

4
2018-04-25 04:50



Pour ProgressDialogs

Pour éviter le rejet automatique du dialogue, vous devez définir le OnClickListener après le ProgressDialog est montré, comme ça:

connectingDialog = new ProgressDialog(this);

connectingDialog.setCancelable(false);
connectingDialog.setCanceledOnTouchOutside(false);

// Create the button but set the listener to a null object.
connectingDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", 
        (DialogInterface.OnClickListener) null )

// Show the dialog so we can then get the button from the view.
connectingDialog.show();

// Get the button from the view.
Button dialogButton = connectingDialog.getButton( DialogInterface.BUTTON_NEGATIVE);

// Set the onClickListener here, in the view.
dialogButton.setOnClickListener( new View.OnClickListener() {

    @Override
    public void onClick ( View v ) {

        // Dialog will not get dismissed until you call dismiss() explicitly.

    }

});

3
2017-07-29 01:38



public class ComentarDialog extends DialogFragment{
private EditText comentario;

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {

    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

    LayoutInflater inflater = LayoutInflater.from(getActivity());
    View v = inflater.inflate(R.layout.dialog_comentar, null);
    comentario = (EditText)v.findViewById(R.id.etxt_comentar_dialog);

    builder.setTitle("Comentar")
           .setView(v)
           .setPositiveButton("OK", null)
           .setNegativeButton("CANCELAR", new DialogInterface.OnClickListener() {
               public void onClick(DialogInterface dialog, int id) {

               }
           });

    return builder.create();
}

@Override
public void onStart() {
    super.onStart();

    //Obtenemos el AlertDialog
    AlertDialog dialog = (AlertDialog)getDialog();

    dialog.setCanceledOnTouchOutside(false);
    dialog.setCancelable(false);//Al presionar atras no desaparece

    //Implementamos el listener del boton OK para mostrar el toast
    dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(TextUtils.isEmpty(comentario.getText())){
               Toast.makeText(getActivity(), "Ingrese un comentario", Toast.LENGTH_SHORT).show();
               return;
            }
            else{
                ((AlertDialog)getDialog()).dismiss();
            }
        }
    });

    //Personalizamos
    Resources res = getResources();

    //Buttons
    Button positive_button = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
    positive_button.setBackground(res.getDrawable(R.drawable.btn_selector_dialog));

    Button negative_button =  dialog.getButton(DialogInterface.BUTTON_NEGATIVE);
    negative_button.setBackground(res.getDrawable(R.drawable.btn_selector_dialog));

    int color = Color.parseColor("#304f5a");

    //Title
    int titleId = res.getIdentifier("alertTitle", "id", "android");
    View title = dialog.findViewById(titleId);
    if (title != null) {
        ((TextView) title).setTextColor(color);
    }

    //Title divider
    int titleDividerId = res.getIdentifier("titleDivider", "id", "android");
    View titleDivider = dialog.findViewById(titleDividerId);
    if (titleDivider != null) {
        titleDivider.setBackgroundColor(res.getColor(R.color.list_menu_divider));
    }
}
}

3
2017-11-10 05:23