Cómo cambiar el tema para AlertDialog

Me preguntaba si alguien podría ayudarme. Estoy tratando de crear un AlertDialog personalizado. Para hacer esto, agregué la siguiente línea de código en styles.xml

  @drawable/color_panel_background   
  • color_panel_background.9.png se encuentra en la carpeta dibujable. Esto también está disponible en la carpeta de res de Android SDK.

La siguiente es la actividad principal.

 package com.customdialog; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.content.DialogInterface; import android.os.Bundle; public class CustomDialog extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); this.setTheme(R.style.CustomAlertDialog); AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage("HELLO!"); builder .setCancelable(false) .setPositiveButton("Yes", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { //MyActivity.this.finish(); } }) .setNegativeButton("No", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { //dialog.cancel(); } }); AlertDialog alertdialog = builder.create(); alertdialog.show(); } } 

Para aplicar el tema a AlertDialog, tuve que establecer el tema en el contexto actual.

Sin embargo, parece que no logro que la aplicación muestre AlertDialog personalizado. ¿Puede alguien ayudarme con esto?

En Dialog.java (Android src) se usa ContextThemeWrapper. Para que pueda copiar la idea y hacer algo como:

AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(this, R.style.AlertDialogCustom));

Y luego pégalo como quieras:

 < ?xml version="1.0" encoding="utf-8"?>    

Estaba teniendo este tema relacionado con el tema AlertDialog usando sdk 1.6 como se describe aquí: http://markmail.org/message/mj5ut56irkrkc4nr

Resolví el problema haciendo lo siguiente:

  new AlertDialog.Builder( new ContextThemeWrapper(context, android.R.style.Theme_Dialog)) 

Espero que esto ayude.

Escribí un artículo en mi blog sobre cómo configurar el diseño de un AlertDialog con archivos de estilo XML. El principal problema es que necesita diferentes definiciones de estilo para diferentes parámetros de diseño. Aquí hay una plantilla basada en el estilo AlertDialog de Holo Light Platform versión 19 para un archivo de estilo que debe abarcar un montón de aspectos de diseño estándar como tamaños de texto y colores de fondo.

        

Estaba luchando con esto: puedes android:alertDialogStyle="@style/AlertDialog" estilo al fondo del diálogo usando android:alertDialogStyle="@style/AlertDialog" en tu tema, pero ignora cualquier configuración de texto que tengas. Como @rflexor dijo anteriormente, no se puede hacer con el SDK antes de Honeycomb (bueno, podrías usar Reflection ).

Mi solución, en pocas palabras, fue darle un estilo al fondo del cuadro de diálogo usando lo anterior, luego establecer un título personalizado y una vista de contenido (usando diseños que son los mismos que los del SDK).

Mi envoltorio

 import com.mypackage.R; import android.app.AlertDialog; import android.content.Context; import android.graphics.drawable.Drawable; import android.view.View; import android.widget.ImageView; import android.widget.TextView; public class CustomAlertDialogBuilder extends AlertDialog.Builder { private final Context mContext; private TextView mTitle; private ImageView mIcon; private TextView mMessage; public CustomAlertDialogBuilder(Context context) { super(context); mContext = context; View customTitle = View.inflate(mContext, R.layout.alert_dialog_title, null); mTitle = (TextView) customTitle.findViewById(R.id.alertTitle); mIcon = (ImageView) customTitle.findViewById(R.id.icon); setCustomTitle(customTitle); View customMessage = View.inflate(mContext, R.layout.alert_dialog_message, null); mMessage = (TextView) customMessage.findViewById(R.id.message); setView(customMessage); } @Override public CustomAlertDialogBuilder setTitle(int textResId) { mTitle.setText(textResId); return this; } @Override public CustomAlertDialogBuilder setTitle(CharSequence text) { mTitle.setText(text); return this; } @Override public CustomAlertDialogBuilder setMessage(int textResId) { mMessage.setText(textResId); return this; } @Override public CustomAlertDialogBuilder setMessage(CharSequence text) { mMessage.setText(text); return this; } @Override public CustomAlertDialogBuilder setIcon(int drawableResId) { mIcon.setImageResource(drawableResId); return this; } @Override public CustomAlertDialogBuilder setIcon(Drawable icon) { mIcon.setImageDrawable(icon); return this; } } 

alert_dialog_title.xml (tomado del SDK)

 < ?xml version="1.0" encoding="utf-8"?>        

alert_dialog_message.xml

 < ?xml version="1.0" encoding="utf-8"?>    

Luego solo use CustomAlertDialogBuilder lugar de AlertDialog.Builder para crear sus diálogos, y simplemente llame a setTitle y setMessage como de costumbre.

   new AlertDialog.Builder(new ContextThemeWrapper(context,R.style.AlertDialogCustom)) .setMessage(Html.fromHtml(Msg)) .setPositiveButton(posBtn, okListener) .setNegativeButton(negBtn, null) .create() .show(); 

Puede asignar un tema directamente cuando inicia el Constructor:

 AlertDialog.Builder builder = new AlertDialog.Builder( getActivity(), R.style.MyAlertDialogTheme); 

Luego personaliza tu tema en tus values/styles.xml

   

Supongo que no se puede hacer. Al menos no con el Constructor. Estoy trabajando con 1.6 y la Implementación en Builder.create () es:

 public AlertDialog create() { final AlertDialog dialog = new AlertDialog(P.mContext); P.apply(dialog.mAlert); [...] } 

que llama al constructor de AlertDialog “no sensible al tema”, que se ve así:

 protected AlertDialog(Context context) { this(context, com.android.internal.R.style.Theme_Dialog_Alert); } 

Hay un segundo constructor en AlertDialog para cambiar los temas:

 protected AlertDialog(Context context, int theme) { super(context, theme); [...] } 

que el Constructor simplemente no llama.

Si el cuadro de diálogo es bastante genérico de todos modos, trataría de escribir una subclase de AlertDialog, llamar al segundo constructor y usar esa clase en lugar del mecanismo Builder.

Una mejor forma de hacer esto es usar un cuadro de diálogo personalizado y personalizar de acuerdo a sus necesidades aquí es un ejemplo de diálogo personalizado …..

enter image description here

 public class CustomDialogUI { Dialog dialog; Vibrator vib; RelativeLayout rl; @SuppressWarnings("static-access") public void dialog(final Context context, String title, String message, final Runnable task) { dialog = new Dialog(context); dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); dialog.setContentView(R.layout.custom); dialog.setCancelable(false); TextView m = (TextView) dialog.findViewById(R.id.message); TextView t = (TextView) dialog.findViewById(R.id.title); final Button n = (Button) dialog.findViewById(R.id.button2); final Button p = (Button) dialog.findViewById(R.id.next_button); rl = (RelativeLayout) dialog.findViewById(R.id.rlmain); t.setText(bold(title)); m.setText(message); dialog.show(); n.setText(bold("Close")); p.setText(bold("Ok")); // color(context,rl); vib = (Vibrator) context.getSystemService(context.VIBRATOR_SERVICE); n.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { vib.vibrate(15); dialog.dismiss(); } }); p.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { vib.vibrate(20); dialog.dismiss(); task.run(); } }); } //customize text style bold italic.... public SpannableString bold(String s) { SpannableString spanString = new SpannableString(s); spanString.setSpan(new StyleSpan(Typeface.BOLD), 0, spanString.length(), 0); spanString.setSpan(new UnderlineSpan(), 0, spanString.length(), 0); // spanString.setSpan(new StyleSpan(Typeface.ITALIC), 0, // spanString.length(), 0); return spanString; } 

}

Aquí está el diseño xml

 < ?xml version="1.0" encoding="utf-8"?>               

Cualquiera que intente hacer esto dentro de un Fragmento (utilizando la biblioteca de soporte, es decir, pre API 11) debería ir con esto:

 public class LoadingDialogFragment extends DialogFragment { public static final String ID = "loadingDialog"; public static LoadingDialogFragment newInstance() { LoadingDialogFragment f = new LoadingDialogFragment(); return f; } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { StyleAlertDialog adb = new StyleAlertDialog(getActivity(), R.style.Your_Style); adb.setView(getActivity().getLayoutInflater().inflate(R.layout.fragment_dialog_layout, null)); return adb; } private class StyleAlertDialog extends AlertDialog { protected StyleAlertDialog(Context context, int theme) { super(context, theme); } } } 

@Rflexor me dio el empujón para extender AlertDialog y exponer el constructor gracias

La solución de Arve Waltin se ve bien, aunque todavía no la he probado. Hay otra solución en caso de que tenga problemas para hacerlo funcionar … Extienda AlertDialog.Builder y anule todos los métodos (por ejemplo, setText , setTitle , setView , etc.) para no configurar el texto / título / vista real del diálogo, pero para crear una nueva vista dentro de la Vista del cuadro de diálogo, haga todo lo que esté a su scope. Entonces eres libre de poner todo a tu gusto.

Para aclarar, en lo que respecta a la clase principal, la Vista está configurada y nada más.

En lo que respecta a su clase extendida personalizada, todo se hace dentro de esa vista.

Para el cuadro de diálogo personalizado:

simplemente llame a super(context,R.style.

) lugar de super(context) en dialog constructor

 public class MyDialog extends Dialog { public MyDialog(Context context) { super(context, R.style.Theme_AppCompat_Light_Dialog_Alert) } } 

Para AlertDialog:

Simplemente crea alertDialog con este constructor:

  new AlertDialog.Builder( new ContextThemeWrapper(context, android.R.style.Theme_Dialog)) 

Se puede hacer simplemente mediante el uso de setView () del constructor. Puede crear cualquier vista de su elección y alimentar al constructor. Esto funciona bien Utilizo una vista de texto personalizada que es renderizada por el generador de diálogo. No configuro el mensaje y este espacio se utiliza para renderizar mi texto principal.

 AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("Title"); builder.setMessage("Description"); builder.setPositiveButton("OK", null); builder.setNegativeButton("Cancel", null); builder.show();