it-swarm.com.ru

Как изменить тему для AlertDialog

Мне было интересно, если кто-нибудь может мне помочь. Я пытаюсь создать собственный AlertDialog. Для этого я добавил следующую строку кода в 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 находится в папке для рисования. Это также доступно в папке Android SDK res.

Следующее является основным видом деятельности.

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();
    }
}

Чтобы применить тему к AlertDialog, мне нужно было установить тему в текущем контексте.

Однако я просто не могу заставить приложение показывать настроенный AlertDialog. Кто-нибудь может мне помочь с этим?

215
Min Soo Kim

В Dialog.Java (Android src) используется ContextThemeWrapper. Таким образом, вы можете скопировать идею и сделать что-то вроде:

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

А затем сделайте стиль, как вы хотите:

<?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>
341
Arve Waltin

У меня была проблема, связанная с темой AlertDialog, с использованием SDK 1.6, как описано здесь: http://markmail.org/message/mj5ut56irkrkc4nr

Я решил проблему, выполнив следующее:

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

Надеюсь это поможет.

89
chee

Я написал статью в своем блоге о том, как настроить макет AlertDialog с файлами стилей XML. Основная проблема заключается в том, что вам нужны разные определения стилей для разных параметров макета. Вот пример, основанный на стиле AlertDialog Holo Light Platform версии 19 для файла стиля, который должен охватывать множество стандартных аспектов макета, таких как размеры текста и цвета фона.

<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>
63
Nantoka

Я боролся с этим - вы можете стилизовать фон диалога, используя Android:alertDialogStyle="@style/AlertDialog" в вашей теме, но он игнорирует любые настройки текста, которые у вас есть. Как сказал выше @rflexor, это невозможно сделать с помощью SDK до Honeycomb (хорошо, вы можете использовать Reflection).

Вкратце, мое решение состояло в том, чтобы стилизовать фон диалогового окна, используя описанное выше, а затем установить пользовательский заголовок и представление контента (используя макеты, такие же, как в SDK).

Моя обертка:

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 (взято из 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>

Затем просто используйте CustomAlertDialogBuilder вместо AlertDialog.Builder для создания своих диалогов и просто вызывайте setTitle и setMessage как обычно.

31
Joseph Earl
 <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();
28
saigopi

Вы можете напрямую назначить тему при запуске Builder:

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

Затем настройте свою тему в своем 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>
19
pha

Я думаю, что это не может быть сделано. По крайней мере, не с Строителем. Я работаю с 1.6 и реализация в Builder.create ():

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

который вызывает конструктор AlertDialog, не связанный с темой, который выглядит следующим образом:

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

В AlertDialog есть второй конструктор для смены тем:

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

что Строитель просто не звонит.

Если бы диалог в любом случае был довольно общим, я бы попытался написать подкласс AlertDialog, вызвать второй конструктор и использовать этот класс вместо механизма Builder.

8
rflexor

для пользовательского диалога:

просто вызовите super(context,R.style.<dialog style>) вместо super(context) в конструкторе диалогов

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


для AlertDialog:

Просто создайте alertDialog с помощью этого конструктора:

 new AlertDialog.Builder(
 new ContextThemeWrapper(context, Android.R.style.Theme_Dialog))
6
Amir Hossein Ghasemi

Лучший способ сделать это - использовать настраиваемое диалоговое окно и настраивать его в соответствии с вашими потребностями, вот пример настраиваемого диалогового окна .....

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;
}

}

Вот макет 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>
4
user2671902

Любой, кто пытается сделать это во фрагменте (используя библиотеку поддержки, то есть до API 11), должен сделать следующее:

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 дал мне толчок для расширения AlertDialog и раскрытия конструктора, спасибо

3
Blundell

Решение Арве Уолтина выглядит хорошо, хотя я еще не проверял его. Есть другое решение, если у вас возникли проблемы с тем, чтобы заставить это работать .... Расширьте AlertDialog.Builder и переопределите все методы (например, setText, setTitle, setView и т.д.), Чтобы не устанавливать фактический текст/заголовок/представление диалога, а создать новый вид в диалоге просмотра все делает там. Тогда вы можете оформить все как угодно.

Чтобы выяснить, что касается родительского класса, представление установлено, и ничего больше.

Что касается вашего пользовательского расширенного класса, все делается в этом представлении.

2
Steven L

Это можно сделать просто с помощью setView () в Builder. Вы можете создать любой вид по вашему выбору и подать в строителя. Это хорошо работает. Я использую пользовательский TextView, который отображается в диалоговом окне. Я не устанавливаю сообщение, и это место используется для отображения моего обычного текста.

0
AKh