J'ai un dialogue avec EditText
pour la saisie. Lorsque je clique sur le bouton "oui" dans la boîte de dialogue, cela valide l'entrée puis ferme la boîte de dialogue. Cependant, si l'entrée est incorrecte, je veux rester dans le même dialogue. Quelle que soit l'entrée, la boîte de dialogue doit être automatiquement fermée lorsque je clique sur le bouton "Non". Comment puis-je désactiver ceci? En passant, j'ai utilisé PositiveButton et NegativeButton pour le bouton de la boîte de dialogue.
EDIT: Cela ne fonctionne que sur l'API 8+, comme indiqué par certains 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();
Voici quelques solutions pour tous les types de boîtes de dialogue, y compris une solution pour AlertDialog.Builder qui fonctionnera à tous les niveaux d'API (fonctionne sous l'API 8, contrairement à l'autre réponse ici). Il existe des solutions pour AlertDialogs utilisant AlertDialog.Builder, DialogFragment et DialogPreference.
Vous trouverez ci-dessous des exemples de code indiquant comment remplacer le gestionnaire de boutons communs par défaut et empêcher la fermeture de la boîte de dialogue pour ces différentes formes de boîte de dialogue. Tous les exemples montrent comment empêcher le bouton positif de fermer la boîte de dialogue.
Remarque: Une description du fonctionnement de la fermeture de la boîte de dialogue sous le capot pour les classes de base Android et la raison pour laquelle les approches suivantes ont été choisies sont les suivantes. ceux qui veulent plus de détails
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.
}
});
@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.
}
});
}
}
@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 examinant 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 de OnCreate (). Quand un bouton est cliqué, le gestionnaire de boutons commun transmet l'événement click au gestionnaire que vous avez transmis dans setButton (), puis les appels annulent la boîte de dialogue.
Si vous souhaitez empêcher une boîte de dialogue de se fermer lorsque vous appuyez sur l'un de ces boutons, vous devez remplacer le gestionnaire de boutons communs pour l'affichage réel du bouton. Comme il est affecté dans OnCreate (), vous devez le remplacer après l'appel de l'implémentation OnCreate () par défaut. OnCreate est appelé dans le processus de la méthode show (). Vous pouvez créer une classe de dialogue personnalisée et remplacer OnCreate () pour appeler super.OnCreate (), puis remplacer les gestionnaires de boutons. Toutefois, si vous créez une boîte de dialogue personnalisée, vous ne bénéficiez pas du générateur gratuitement. ?
Ainsi, en utilisant un dialogue tel qu'il est conçu, mais en contrôlant le moment où il est rejeté, une approche consiste à appeler dialog.Show () en premier, puis à obtenir une référence au bouton à l'aide de dialog.getButton () pour remplacer le gestionnaire de clics. Une autre approche consiste à utiliser setOnShowListener () et à mettre en œuvre la recherche de la vue des boutons 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 envoyé à un gestionnaire s'exécutant sur le thread ayant créé cette boîte de dialogue. Ainsi, étant donné que votre message OnShowListener est appelé par un message publié dans la file de messages, il est techniquement possible que l'appel de votre écouteur soit retardé un certain temps après la fin de la diffusion.
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 appelant show () fonctionnera sur le fil principal de l'interface graphique, cela signifie que tout code que vous suivez avec show () sera exécuté avant tout autre code sur ce fil, alors que le minutage de la méthode OnShowListener est à la merci de la file d'attente des messages.
J'ai écrit une classe simple (un AlertDialogBuilder) que vous pouvez utiliser pour désactiver la fonctionnalité de suppression automatique lorsque vous appuyez sur les boutons de la boîte de dialogue.
Il est également compatible avec Android 1.6, de sorte qu'il ne fait pas appel à OnShowListener (disponible uniquement pour les 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 spectacle() méthode. J'ai ajouté des méthodes comme setCanceledOnTouchOutside () et setOnDismissListener afin que vous puissiez toujours les définir directement sur le constructeur.
Je l'ai testé sur Android 1.6, 2.x, 3.x et 4.x, de sorte qu'il devrait fonctionner assez bien. Si vous rencontrez 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;
}
}
EDIT Voici un petit exemple d'utilisation de 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
Je voudrais présenter une autre réponse du point de vue de l'expérience utilisateur.
Pourquoi voudriez-vous empêcher une boîte de dialogue de se fermer quand un bouton est cliqué? C'est probablement parce que vous avez une boîte de dialogue personnalisée dans laquelle l'utilisateur n'a pas encore choisi ou n'a pas encore tout renseigné. Et s'ils ne sont pas terminés, vous ne devriez pas leur permettre de cliquer du tout sur le bouton positif. Il suffit de le désactiver jusqu'à ce que tout soit prêt.
Les autres réponses ici donnent beaucoup d’astuces pour annuler le clic positif du bouton. Si cela était important à faire, Android n'aurait pas fait une méthode pratique pour le faire? Ils n'ont pas.
Au lieu de cela, le Guide de conception des dialogues montre un exemple d'une telle situation. Le bouton OK est désactivé jusqu'à ce que l'utilisateur fasse son choix. Aucune astuce primordiale n'est nécessaire. Il est évident pour l'utilisateur qu'il reste encore quelque chose à faire avant de continuer.
Voir le documentation Android pour créer une disposition de dialogue personnalisée . Il est recommandé de placer votre AlertDialog
dans un DialogFragment
. Il vous suffit ensuite de configurer les écouteurs sur les éléments de présentation pour savoir quand activer ou désactiver le bouton positif.
EditText
, utilisez TextWatcher .Le bouton positif peut être désactivé comme ceci:
AlertDialog dialog = (AlertDialog) getDialog();
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
Voici un DialogFragment
complet 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");
Notes
Le bouton est toujours null
dans onCreateDialog
alors je l’ai désactivé dans onResume
. Cela a pour effet indésirable de le désactiver à nouveau si l'utilisateur bascule vers une autre application puis revient sans fermer la boîte de dialogue. Cela pourrait être résolu en désélectionnant également les choix de l'utilisateur ou en appelant un Runnable
à partir de onCreateDialog
pour désactiver le bouton lors de 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);
}
});
Inspiré par la réponse de Tom, je crois que l’idée est la suivante:
onClickListener
lors de la création du dialogue sur null
onClickListener
après que le dialogue soit affiché.Vous pouvez remplacer le onShowListener
comme Tom. Alternativement, vous pouvez
show()
d'AlertDialogonClickListener
comme suit (légèrement 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);
}
});
Pour pré API 8, j’ai résolu le problème en utilisant un drapeau booléen, un écouteur de renvoi et un nouvel appel à dialog.show si, au cas, le contenu de l’édition ne pouvait pas être 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;
La réponse à ce lien est une solution simple, compatible depuis l’API 3. Elle est très similaire à la solution de Tom Bollwitt, mais n’utilise pas OnShowListener, qui est moins compatible.
Oui, vous pouvez. Vous devez essentiellement:
- Créer la boîte de dialogue avec DialogBuilder
- show () le dialogue
- Recherchez les boutons dans la boîte de dialogue affichée et remplacez leur onClickListener.
J'ai fait des adaptations mineures au code de Kamen depuis que je développais 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!
Ce code fonctionnera pour vous, car j'ai eu un problème similaire et cela a fonctionné pour moi. :)
1- Redéfinissez la méthode Onstart () dans votre classe de dialogue de fragment.
@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
}
}
});
}
}
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));
}
}
}
Pour éviter que la boîte de dialogue ne soit automatiquement fermée, vous devez définir la OnClickListener
après l'affichage de la variable ProgressDialog
, comme suit:
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.
}
});
vous pouvez ajouter builder.show (); après le message de validation avant le retour;
comme ça
public void login()
{
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setView(R.layout.login_layout);
builder.setTitle("Login");
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int id)
{
dialog.cancel();
}
});// put the negative button before the positive button, so it will appear
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int id)
{
Dialog d = (Dialog) dialog;
final EditText etUserName = (EditText) d.findViewById(R.id.etLoginName);
final EditText etPassword = (EditText) d.findViewById(R.id.etLoginPassword);
String userName = etUserName.getText().toString().trim();
String password = etPassword.getText().toString().trim();
if (userName.isEmpty() || password.isEmpty())
{
Toast.makeText(getApplicationContext(),
"Please Fill all fields", Toast.LENGTH_SHORT).show();
builder.show();// here after validation message before retrun
// it will reopen the dialog
// till the user enter the right condition
return;
}
user = Manager.get(getApplicationContext()).getUserByName(userName);
if (user == null)
{
Toast.makeText(getApplicationContext(),
"Error ethier username or password are wrong", Toast.LENGTH_SHORT).show();
builder.show();
return;
}
if (password.equals(user.getPassword()))
{
etPassword.setText("");
etUserName.setText("");
setLogged(1);
setLoggedId(user.getUserId());
Toast.makeText(getApplicationContext(),
"Successfully logged in", Toast.LENGTH_SHORT).show();
dialog.dismiss();// if every thing is ok then dismiss the dialog
}
else
{
Toast.makeText(getApplicationContext(),
"Error ethier username or password are wrong", Toast.LENGTH_SHORT).show();
builder.show();
return;
}
}
});
builder.show();
}
Pour empêcher la boîte de dialogue de se fermer lorsque vous cliquez dessus et ne devrait se fermer que si Internet est disponible
J'essaie de faire la même chose, car je ne veux pas que la boîte de dialogue soit fermée tant que l'internet n'est pas connecté.
Voici mon code
AlertDialog.Builder builder=new AlertDialog.Builder(MainActivity.this); builder.setTitle("Internet Not Connected");
if(ifConnected()){
Toast.makeText(this, "Connected or not", Toast.LENGTH_LONG).show();
}
else{
builder.setPositiveButton("Retry", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
if(!ifConnected())
{
builder.show();
}
}
}).setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
finish();
}
});
builder.show();
}
Et voici mon code de gestionnaire de connectivité
private boolean ifConnected()
{
ConnectivityManager connectivityManager= (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo=connectivityManager.getActiveNetworkInfo();
return networkInfo!=null && networkInfo.isConnected();
}
Si vous utilisez material design
, je vous conseillerais de vérifier dialogues-matériels . Il a corrigé plusieurs problèmes liés aux bugs Android actuellement ouverts (voir 78088 ), mais plus important encore pour ce ticket il a un drapeau autoDismiss
qui peut être défini avec l’utilisation de Builder
.
Utilisez une mise en page personnalisée pour votre DialogFragment
et ajoutez un LinearLayout
sous votre contenu, qui peut être stylé sans bordure pour correspondre à Google Material. Conception. Recherchez ensuite les boutons nouvellement créés et remplacez leur OnClickListener
.
Exemple:
public class AddTopicFragment extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Get the layout inflater
LayoutInflater inflater = getActivity().getLayoutInflater();
final View dialogView = inflater.inflate(R.layout.dialog_add_topic, null);
Button saveTopicDialogButton = (Button) dialogView.findViewById(R.id.saveTopicDialogButton);
Button cancelSaveTopicDialogButton = (Button) dialogView.findViewById(R.id.cancelSaveTopicDialogButton);
final AppCompatEditText addTopicNameET = (AppCompatEditText) dialogView.findViewById(R.id.addTopicNameET);
final AppCompatEditText addTopicCreatedByET = (AppCompatEditText) dialogView.findViewById(R.id.addTopicCreatedByET);
saveTopicDialogButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// validate inputs
if(addTopicNameET.getText().toString().trim().isEmpty()){
addTopicNameET.setError("Topic name can't be empty");
addTopicNameET.requestFocus();
}else if(addTopicCreatedByET.getText().toString().trim().isEmpty()){
addTopicCreatedByET.setError("Topic created by can't be empty");
addTopicCreatedByET.requestFocus();
}else {
// save topic to database
Topic topic = new Topic();
topic.name = addTopicNameET.getText().toString().trim();
topic.createdBy = addTopicCreatedByET.getText().toString().trim();
topic.createdDate = new Date().getTime();
topic.save();
AddTopicFragment.this.dismiss();
}
}
});
cancelSaveTopicDialogButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AddTopicFragment.this.dismiss();
}
});
// Inflate and set the layout for the dialog
// Pass null as the parent view because its going in the dialog layout
builder.setView(dialogView)
.setMessage(getString(R.string.add_topic_message));
return builder.create();
}
}
dialog_add_topic.xml :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:orientation="vertical"
Android:padding="@dimen/activity_horizontal_margin"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<Android.support.design.widget.TextInputLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
app:errorEnabled="true">
<Android.support.v7.widget.AppCompatEditText
Android:id="@+id/addTopicNameET"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:hint="Topic Name"
Android:inputType="textPersonName"
Android:maxLines="1" />
</Android.support.design.widget.TextInputLayout>
<Android.support.design.widget.TextInputLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
app:errorEnabled="true">
<Android.support.v7.widget.AppCompatEditText
Android:id="@+id/addTopicCreatedByET"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:hint="Created By"
Android:inputType="textPersonName"
Android:maxLines="1" />
</Android.support.design.widget.TextInputLayout>
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:orientation="horizontal">
<Button
Android:text="@string/cancel"
Android:layout_weight="1"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:id="@+id/cancelSaveTopicDialogButton"
style="@style/Widget.AppCompat.Button.ButtonBar.AlertDialog" />
<Button
Android:text="@string/save"
Android:layout_weight="1"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:id="@+id/saveTopicDialogButton"
style="@style/Widget.AppCompat.Button.ButtonBar.AlertDialog" />
</LinearLayout>
</LinearLayout>
Mettez ceci dans votre classe utilitaire.
/*
* Show Dialog with Title, Message, Button1, Button2 with Button1 and Button2 Listener
*/
public AlertDialog showDialog(Context ctx, String title, String msg,
String btn1, String btn2,
OnClickListener listener1,
OnClickListener listener2) {
AlertDialog.Builder builder = new AlertDialog.Builder(ctx)
.setTitle(title)
.setMessage(msg)
.setCancelable(true)
.setPositiveButton(btn1, listener1);
if (btn2 != null)
builder.setNegativeButton(btn2, listener2);
AlertDialog alert = builder.create();
return alert;
}
Ensuite, lorsque vous devez afficher le dialogue
showDialog(getActivity(), "Title", "Message", "First button title", "Second button title",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
// TODO: 5/14/2018 first button clicked
}
},
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
// TODO: 5/14/2018 second button clicked
}
}).show();
C'est probablement une réponse très tardive, mais l'utilisation de setCancelable fera l'affaire.
alertDial.setCancelable(false);
Il pourrait être construit de la manière la plus simple:
Boîte de dialogue d'alerte avec vue personnalisée et avec deux boutons (positif et négatif).
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()).setTitle(getString(R.string.select_period));
builder.setPositiveButton(getString(R.string.ok), null);
builder.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// Click of Cancel Button
}
});
LayoutInflater li = LayoutInflater.from(getActivity());
View promptsView = li.inflate(R.layout.dialog_date_picker, null, false);
builder.setView(promptsView);
DatePicker startDatePicker = (DatePicker)promptsView.findViewById(R.id.startDatePicker);
DatePicker endDatePicker = (DatePicker)promptsView.findViewById(R.id.endDatePicker);
final AlertDialog alertDialog = builder.create();
alertDialog.show();
Button theButton = alertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
theButton.setOnClickListener(new CustomListener(alertDialog, startDatePicker, endDatePicker));
CustomClickLister de bouton positif de journal d'alerte:
private class CustomListener implements View.OnClickListener {
private final Dialog dialog;
private DatePicker mStartDp, mEndDp;
public CustomListener(Dialog dialog, DatePicker dS, DatePicker dE) {
this.dialog = dialog;
mStartDp = dS;
mEndDp = dE;
}
@Override
public void onClick(View v) {
int day1 = mStartDp.getDayOfMonth();
int month1= mStartDp.getMonth();
int year1 = mStartDp.getYear();
Calendar cal1 = Calendar.getInstance();
cal1.set(Calendar.YEAR, year1);
cal1.set(Calendar.MONTH, month1);
cal1.set(Calendar.DAY_OF_MONTH, day1);
int day2 = mEndDp.getDayOfMonth();
int month2= mEndDp.getMonth();
int year2 = mEndDp.getYear();
Calendar cal2 = Calendar.getInstance();
cal2.set(Calendar.YEAR, year2);
cal2.set(Calendar.MONTH, month2);
cal2.set(Calendar.DAY_OF_MONTH, day2);
if(cal2.getTimeInMillis()>=cal1.getTimeInMillis()){
dialog.dismiss();
Log.i("Dialog", "Dismiss");
// Condition is satisfied so do dialog dismiss
}else {
Log.i("Dialog", "Do not Dismiss");
// Condition is not satisfied so do not dialog dismiss
}
}
}
Fait