Evitar que DialogFragment se rechace cuando se hace clic en el botón

Tengo un DialogFragment con una vista de encargo que contiene dos campos del texto donde el usuario debe introducir su username y contraseña. Cuando se hace clic en el botón positivo, quiero validar que el usuario realmente ingresó algo antes de descartar el diálogo.

public class AuthenticationDialog extends DialogFragment { public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); LayoutInflater inflater = getActivity().getLayoutInflater(); builder.setView(inflater.inflate(R.layout.authentication_dialog, null)) .setPositiveButton(getResources().getString(R.string.login), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { // TODO } }) .setNegativeButton(getResources().getString(R.string.reset), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { // TODO } }); return builder.create(); } } 

Entonces, ¿cómo puedo evitar que el diálogo de despido? ¿Hay algún método que debo anular?

4 Solutions collect form web for “Evitar que DialogFragment se rechace cuando se hace clic en el botón”

Anule los controladores de botones predeterminados en OnStart () para hacer esto.

 @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(); } @Override public void onStart() { super.onStart(); //super.onStart() is where dialog.show() is actually called on the underlying dialog, so we have to do it after this point 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) dismiss(); //else dialog stays open. Make sure you have an obvious way to close the dialog especially if you set cancellable to false. } }); } } 

Vea mi respuesta aquí https://stackoverflow.com/a/15619098/579234 para más explicaciones y ejemplos sobre otros tipos de diálogo también.

Gracias a Luksprog, pude encontrar una solución.

AuthenticationDialog.java :

 public class AuthenticationDialog extends DialogFragment implements OnClickListener { public interface AuthenticationDialogListener { void onAuthenticationLoginClicked(String username, String password); void onAuthenticationResetClicked(String username); } private AuthenticationDialogListener mListener; private EditText mUsername; private EditText mPassword; private Button mReset; private Button mLogin; public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.authentication_dialog, container); this.getDialog().setTitle(R.string.login_title); mUsername = (EditText) view.findViewById(R.id.username_field); mPassword = (EditText) view.findViewById(R.id.password_field); mReset = (Button) view.findViewById(R.id.reset_button); mLogin = (Button) view.findViewById(R.id.login_button); mReset.setOnClickListener(this); mLogin.setOnClickListener(this); return view; } public void onAttach(Activity activity) { super.onAttach(activity); // Verify that the host activity implements the callback interface try { // Instantiate the NoticeDialogListener so we can send events to the host mListener = (AuthenticationDialogListener) activity; } catch (ClassCastException e) { // The activity doesn't implement the interface, throw exception throw new ClassCastException(activity.toString() + " must implement AuthenticationDialogListener"); } } public void onClick(View v) { if (v.equals(mLogin)) { if (mUsername.getText().toString().length() < 1 || !mUsername.getText().toString().contains("@")) { Toast.makeText(getActivity(), R.string.invalid_email, Toast.LENGTH_SHORT).show(); return; } else if (mPassword.getText().toString().length() < 1) { Toast.makeText(getActivity(), R.string.invalid_password, Toast.LENGTH_SHORT).show(); return; } else { mListener.onAuthenticationLoginClicked(mUsername.getText().toString(), mPassword.getText().toString()); this.dismiss(); } } else if (v.equals(mReset)) { mListener.onAuthenticationResetClicked(mUsername.getText().toString()); } } } 

Authentication_dialog.xml :

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" > <EditText android:id="@+id/username_field" android:inputType="textEmailAddress" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:layout_marginLeft="4dp" android:layout_marginRight="4dp" android:layout_marginBottom="4dp" android:hint="@string/username" /> <EditText android:id="@+id/password_field" android:inputType="textPassword" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="4dp" android:layout_marginLeft="4dp" android:layout_marginRight="4dp" android:layout_marginBottom="12dp" android:fontFamily="sans-serif" android:hint="@string/password" /> <View android:layout_width="fill_parent" android:layout_height="1dip" android:background="?android:attr/dividerVertical" /> <LinearLayout style="?android:attr/buttonBarStyle" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:paddingTop="0dp" android:measureWithLargestChild="true" > <Button android:id="@+id/reset_button" style="?android:attr/buttonBarButtonStyle" android:layout_height="wrap_content" android:layout_width="0dp" android:layout_weight="1.0" android:text="@string/reset" /> <Button android:id="@+id/login_button" style="?android:attr/buttonBarButtonStyle" android:layout_height="wrap_content" android:layout_width="0dp" android:layout_weight="1.0" android:text="@string/login" /> </LinearLayout> </LinearLayout> 

Esta es la solución "sweetspot" de las respuestas de Karakuri y Sogger. Karakuri estaba en el camino correcto, sin embargo, sólo puede obtener el botón de esa manera si ya se muestra (es nulo de lo contrario, como se indica en los comentarios). Esta es la razón por la cual la respuesta de Sogger funciona, sin embargo prefiero la configuración en el mismo método, que es onCreateDialog , y no adicionalmente en onStart . La solución es envolver la recuperación de los botones en el OnShowListener del diálogo.

 public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); // your dialog setup, just leave the OnClick-listeners empty here and use the ones below final AlertDialog dialog = builder.create(); dialog.setOnShowListener(new DialogInterface.OnShowListener() { @Override public void onShow(final DialogInterface dialog) { Button positiveButton = ((AlertDialog) dialog).getButton(DialogInterface.BUTTON_POSITIVE); positiveButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(final View v) { // TODO - call 'dismiss()' only if you need it } }); Button negativeButton = ((AlertDialog) dialog).getButton(DialogInterface.BUTTON_NEGATIVE); // same for negative (and/or neutral) button if required } }); return dialog; } 

Podrías volver a abrir el diálogo. O, puede mantener el botón positivo deshabilitado hasta que haya entrada en ambos campos. Esto es bastante fácil si usted está creando el diseño en onCreateVew() . Si está utilizando la clase AlertDialog.Builder lugar, puede obtener un identificador para el botón de la siguiente manera:

 AlertDialog.Builder builder = new AlertDialog.Builder(context); /* ... */ Dialog dialog = builder.create(); Button positiveButton = ((AlertDialog) dialog).getButton(DialogInterface.BUTTON_POSITIVE); /* now you can affect the button */ 
  • Detener usuario multi-clic en edittext para abrir varios diálogos
  • Obtener contexto dentro de onClick (DialogInterface v, int buttonId)?
  • Agregar a un control SlidingDrawer?
  • En EditText, aparece un diálogo al hacer clic en un subconjunto específico de texto
  • Phonegap 2.4.0 con Android 4.2 - comportamiento de doble clic extraño
  • Abrir la lista de contactos del dispositivo en el evento de clic de botón
  • GetCheckedRadioButtonId () devuelve int inútil?
  • ((Botón)) dentro de un servicio no funciona
  • Vista no se puede resolver a un tipo
  • Cómo borrar el edittext cuando onclick en el botón
  • ¿Cómo pasar el evento onClick a su padre en Android?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.