studio - android alertdialog custom style
Cómo cambiar el tema para AlertDialog (13)
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
<resources>
<style name="CustomAlertDialog" parent="android:Theme.Dialog.Alert">
<item name="android:windowBackground">@drawable/color_panel_background</item>
</style>
</resources>
- color_panel_background.9.png está ubicado en una carpeta dibujable. Esto también está disponible en la carpeta de resolución 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 un AlertDialog, tuve que establecer el tema en el contexto actual.
Sin embargo, parece que no consigo que la aplicación muestre AlertDialog personalizado. ¿Puede alguien ayudarme con esto?
Cualquier persona que intente hacer esto dentro de un Fragmento (usando la biblioteca de soporte, es decir, la API previa 11) debería hacer 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 al constructor gracias
En Dialog.java (Android src) se utiliza un ContextThemeWrapper. Para que puedas copiar la idea y hacer algo como:
AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(this, R.style.AlertDialogCustom));
Y luego el estilo que quieras:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AlertDialogCustom" parent="@android:style/Theme.Dialog">
<item name="android:textColor">#00FF00</item>
<item name="android:typeface">monospace</item>
<item name="android:textSize">10sp</item>
</style>
</resources>
Estaba luchando con esto: puedes android:alertDialogStyle="@style/AlertDialog"
el fondo del diálogo con 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, puedes usar Reflection
).
Mi solución, en pocas palabras, fue diseñar el 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"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<LinearLayout
android:id="@+id/title_template"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layout_marginTop="6dip"
android:layout_marginBottom="9dip"
android:layout_marginLeft="10dip"
android:layout_marginRight="10dip">
<ImageView android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:paddingTop="6dip"
android:paddingRight="10dip"
android:src="@drawable/ic_dialog_alert" />
<TextView android:id="@+id/alertTitle"
style="@style/?android:attr/textAppearanceLarge"
android:singleLine="true"
android:ellipsize="end"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<ImageView android:id="@+id/titleDivider"
android:layout_width="fill_parent"
android:layout_height="1dip"
android:scaleType="fitXY"
android:gravity="fill_horizontal"
android:src="@drawable/divider_horizontal_bright" />
</LinearLayout>
alert_dialog_message.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/scrollView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="2dip"
android:paddingBottom="12dip"
android:paddingLeft="14dip"
android:paddingRight="10dip">
<TextView android:id="@+id/message"
style="?android:attr/textAppearanceMedium"
android:textColor="@color/dark_grey"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="5dip" />
</ScrollView>
Luego solo use CustomAlertDialogBuilder
lugar de AlertDialog.Builder
para crear sus cuadros de diálogo, y simplemente llame a setTitle
y setMessage
como de costumbre.
He escrito un article en mi blog sobre cómo configurar el diseño de un AlertDialog con archivos de estilo XML. El problema principal es que necesita diferentes definiciones de estilo para diferentes parámetros de diseño. Aquí hay una placa de calderas basada en el estilo de 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.
<style name="AppBaseTheme" parent="android:Theme.Holo.Light">
...
<item name="android:alertDialogTheme">@style/MyAlertDialogTheme</item>
<item name="android:alertDialogStyle">@style/MyAlertDialogStyle</item>
...
</style>
<style name="MyBorderlessButton">
<!-- Set background drawable and text size of the buttons here -->
<item name="android:background">...</item>
<item name="android:textSize">...</item>
</style>
<style name="MyButtonBar">
<!-- Define a background for the button bar and a divider between the buttons here -->
<item name="android:divider">....</item>
<item name="android:dividerPadding">...</item>
<item name="android:showDividers">...</item>
<item name="android:background">...</item>
</style>
<style name="MyAlertDialogTitle">
<item name="android:maxLines">1</item>
<item name="android:scrollHorizontally">true</item>
</style>
<style name="MyAlertTextAppearance">
<!-- Set text size and color of title and message here -->
<item name="android:textSize"> ... </item>
<item name="android:textColor">...</item>
</style>
<style name="MyAlertDialogTheme">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowTitleStyle">@style/MyAlertDialogTitle</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item>
<item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
<item name="android:windowIsFloating">true</item>
<item name="android:textAppearanceMedium">@style/MyAlertTextAppearance</item>
<!-- If you don''t want your own button bar style use
@android:style/Holo.Light.ButtonBar.AlertDialog
and
?android:attr/borderlessButtonStyle
instead of @style/MyButtonBar and @style/MyBorderlessButton -->
<item name="android:buttonBarStyle">@style/MyButtonBar</item>
<item name="android:buttonBarButtonStyle">@style/MyBorderlessButton</item>
</style>
<style name="MyAlertDialogStyle">
<!-- Define background colors of title, message, buttons, etc. here -->
<item name="android:fullDark">...</item>
<item name="android:topDark">...</item>
<item name="android:centerDark">...</item>
<item name="android:bottomDark">...</item>
<item name="android:fullBright">...</item>
<item name="android:topBright">...</item>
<item name="android:centerBright">...</item>
<item name="android:bottomBright">...</item>
<item name="android:bottomMedium">...</item>
<item name="android:centerMedium">...</item>
</style>
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 conseguir que funcione ... Extienda AlertDialog.Builder
y anule todos los métodos (por ejemplo, setText
, setTitle
, setView
, etc.) para no configurar el texto / título / vista del diálogo real, pero para crear una nueva vista dentro de la Vista del diálogo, haga todo lo que esté allí. Entonces eres libre de estilizar todo lo que quieras.
Para aclarar, en lo que concierne a la clase padre, se establece la Vista, y nada más.
En lo que respecta a su clase extendida personalizada, todo se hace dentro de esa vista.
Puede asignar un tema directamente al iniciar el Generador:
AlertDialog.Builder builder = new AlertDialog.Builder(
getActivity(), R.style.MyAlertDialogTheme);
Luego personaliza tu tema en tus values/styles.xml
<!-- Alert Dialog -->
<style name="MyAlertDialogTheme" parent="Theme.AppCompat.Dialog.Alert">
<item name="colorAccent">@color/colorAccent</item>
<item name="android:colorBackground">@color/alertDialogBackground</item>
<item name="android:windowBackground">@color/alertDialogBackground</item>
</style>
Se puede hacer simplemente usando el setView () del constructor. Puede crear cualquier vista de su elección y alimentar al constructor. Esto funciona bien. Utilizo un TextView personalizado que es generado por el generador de diálogo. No configuro el mensaje y este espacio se utiliza para renderizar mi vista de texto.
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 "no sensible al tema" de AlertDialog, 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 temas:
protected AlertDialog(Context context, int theme) {
super(context, theme);
[...]
}
que el Constructor simplemente no llama.
De todos modos, si el Diálogo es bastante genérico, intentaría escribir una subclase de AlertDialog, llamar al segundo constructor y usar esa clase en lugar del mecanismo del Generador.
Tenía un problema relacionado con el tema de AlertDialog
utilizando 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.
Para el diálogo personalizado:
simplemente llame a super(context,R.style.<dialog style>)
lugar de super(context)
en el constructor de diálogos
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))
Una mejor forma de hacer esto es usar un cuadro de diálogo personalizado y personalizarlo según sus necesidades.
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"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00000000"
>
<RelativeLayout
android:id="@+id/rlmain"
android:layout_width="fill_parent"
android:layout_height="150dip"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:background="#569CE3" >
<RelativeLayout
android:id="@+id/relativeLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginLeft="25dip"
android:layout_marginTop="10dip" >
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="Are you Sure?"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#ffffff"
android:textSize="13dip" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/relativeLayout2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/relativeLayout1"
android:layout_alignRight="@+id/relativeLayout1"
android:layout_below="@+id/relativeLayout1"
android:layout_marginTop="5dip" >
</RelativeLayout>
<ProgressBar
android:id="@+id/process"
style="?android:attr/progressBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginRight="3dip"
android:layout_marginTop="3dip" />
<RelativeLayout
android:id="@+id/relativeLayout3"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/relativeLayout2"
android:layout_below="@+id/relativeLayout2"
android:layout_toLeftOf="@+id/process" >
<TextView
android:id="@+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#ffffff"
android:textSize="13dip"/>
</RelativeLayout>
<Button
android:id="@+id/next_button"
android:layout_width="90dip"
android:layout_height="35dip"
android:layout_alignParentBottom="true"
android:textColor="@drawable/button_text_color"
android:background="@drawable/blue_button"
android:layout_marginBottom="5dp"
android:textSize="10dp"
android:layout_alignRight="@+id/relativeLayout3"
android:text="Okay" />
<Button
android:id="@+id/button2"
android:text="Cancel"
android:textColor="@drawable/button_text_color"
android:layout_width="90dip"
android:layout_height="35dip"
android:layout_marginBottom="5dp"
android:background="@drawable/blue_button"
android:layout_marginRight="7dp"
android:textSize="10dp"
android:layout_alignParentBottom="true"
android:layout_toLeftOf="@+id/next_button"
/>
</RelativeLayout>
<style name="AlertDialogCustom" parent="Theme.AppCompat.Light.Dialog.Alert">
<!-- Used for the buttons -->
<item name="colorAccent">@color/colorAccent</item>
<!-- Used for the title and text -->
<item name="android:textColorPrimary">#FFFFFF</item>
<!-- Used for the background -->
<item name="android:background">@color/teal</item>
</style>
new AlertDialog.Builder(new ContextThemeWrapper(context,R.style.AlertDialogCustom))
.setMessage(Html.fromHtml(Msg))
.setPositiveButton(posBtn, okListener)
.setNegativeButton(negBtn, null)
.create()
.show();
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Title");
builder.setMessage("Description");
builder.setPositiveButton("OK", null);
builder.setNegativeButton("Cancel", null);
builder.show();