Android-стиль AlertDialog

у меня есть диалоговое окно оповещения в приложении, как показано ниже.

enter image description here

Я хочу, чтобы заголовок и строка, которая отделяет тело заголовка сообщения, были оранжевого цвета. как я могу это сделать? То, что я пробовал, использует пользовательский стиль, как показано ниже. Но это не сработало.

<style name="AboutDialog" parent="@android:style/Theme.Dialog">
  <item name="android:textColor">#E5492A</item>
</style>

мой код диалога оповещения:

AlertDialog.Builder alertDialog = new AlertDialog.Builder( new ContextThemeWrapper(MainActivity.context, R.style.AboutDialog));
alertDialog.setTitle("Sample");
        alertDialog.setMessage(R.string.rate_dialog_text);
        alertDialog.setPositiveButton(R.string.rate_now_text,
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        MainActivity.context.startActivity(new Intent(
                                Intent.ACTION_VIEW, Uri
                                        .parse("market://details?id="
                                                + MainActivity.APP_PNAME)));
                        if (editor != null) {
                            editor.putBoolean("dontshowagain", true);
                            editor.commit();
                        }
                        dialog.dismiss();

                    }
                });

        alertDialog.setNeutralButton(R.string.remind_later_text,
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                });

        alertDialog.setNegativeButton(R.string.no_thanks_text,
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        if (editor != null) {
                            editor.putBoolean("dontshowagain", true);
                            editor.commit();
                        }
                        dialog.dismiss();
                    }
                });

        return alertDialog.create();

    }

4 ответов


вместо:

AlertDialog.Builder alertDialog = new AlertDialog.Builder(
    new ContextThemeWrapper(MainActivity.context, R.style.AboutDialog));

попробуйте это:

AlertDialog.Builder alertDialog = new AlertDialog.Builder(this, R.style.AboutDialog);

Примечание: это доступно только для API 11 (Android 3.0) и выше.

Если вам нужно поддерживать Android AlertDialog

EDIT добавлен действительно неряшливый Хак на основе отражения

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

после того, как вы построили диалог и как раз перед тем, как вы хотите вернуть его, вместо этого:

return alertDialog.create();

этого:

AlertDialog ad = alertDialog.create(); // Create the dialog
// Add listener so we can modify the dialog before it is shown
ad.setOnShowListener(new DialogInterface.OnShowListener() {
    @Override
    public void onShow(DialogInterface dialogInterface) {
        // Set the text color on the dialog title and separator
        setTextColor(dialogInterface, 0xFFE5492A);
    }
});
return ad;

теперь добавьте этот очень неприятный метод на основе отражения:

public void setTextColor(DialogInterface alert, int color) {
    try {
        Class c = alert.getClass();
        Field mAlert = c.getDeclaredField("mAlert");
        mAlert.setAccessible(true);
        Object alertController = mAlert.get(alert);
        c = alertController.getClass();
        Field mTitleView = c.getDeclaredField("mTitleView");
        mTitleView.setAccessible(true);
        Object dialogTitle = mTitleView.get(alertController);
        TextView dialogTitleView = (TextView)dialogTitle;
        // Set text color on the title
        dialogTitleView.setTextColor(color);
        // To find the horizontal divider, first
        //  get container around the Title
        ViewGroup parent = (ViewGroup)dialogTitleView.getParent();
        // Then get the container around that container
        parent = (ViewGroup)parent.getParent();
        for (int i = 0; i < parent.getChildCount(); i++) {
            View v = parent.getChildAt(i);
            if (v instanceof ImageView) {
                // We got an ImageView, that should be the separator
                ImageView im = (ImageView)v;
                // Set a color filter on the image
                im.setColorFilter(color);
            }
        }
    } catch (Exception e) {
        // Ignore any exceptions, either it works or it doesn't
    }
}

я проверил это на Android 2.2 и Android 4.0 и она работает. Он может не делать именно то, что вы хотите, поэтому вам нужно попробовать. Я не могу гарантировать, что он будет работать на всех устройствах или на будущих версиях Android, так как это зависит от пути the AlertDialog класс реализован (если они изменят это в будущем, это, вероятно, больше не будет работать).

просто несколько заметок для тех, кто заботится:

  1. причина, по которой я использую setOnShowListener() это потому что вы не можете добраться до внутренней View объекты AlertDialog пользы до тех пор пока после того как они не будут надуты. Они не раздуваются сразу, когда вы создаете AlertDialog, это происходит спустя некоторое время. Используя слушателя мы можем получить контроль после макет завышен, но перед это.

  2. я использую отражение для доступа к внутренним переменным-членам в AlertDialog реализация. Как только я получу доступ к TextView который содержит заголовок, я должен обезьяна вокруг, чтобы найти горизонтальную линию, которая используется для отделения заголовка от сообщения. Для этого я получаю Layout что окружает название (это Layout содержит значок предупреждения и текст заголовка). Тогда я получаю Layout что окружает то (это Layout обертывает значок, текст заголовка и разделитель). Затем я смотрю на всех детей окружающего макета и устанавливаю цвет на всех ImageView объекты. Разделитель реализован как ImageView используя drawable, поэтому невозможно просто изменить цвет. Примечание: альтернатива использованию setColorFilter() было бы заменить drawable в ImageView подходящим цветным drawable здесь.

Спасибо за вызов, это было забавно понять это: - D


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

final AlertDialog.Builder demoDialog = new AlertDialog.Builder(this);
        final LayoutInflater inflator = this.getLayoutInflater();
        final View view = inflator.inflate(R.layout.passcode_req_dialog_template, null);

        demoDialog.setView(view)

            .setPositiveButton(R.string.ok_button_text, new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {

                }
            })

            .setNegativeButton(R.string.cancel_button_text, new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {

                }
            });

        final AlertDialog dialog = passwordDialog.create();
        dialog.show();
        dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                //Get the work done here when pressing positive button
                dialog.dismiss(); 
            }
        });

        dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                //Get the work done here when pressing negative button
                dialog.dismiss();   
            }
        });

попробуйте создать custom layout для диалога и укажите, что layout в диалог оповещения с помощью

dialog.setContentView(R.layout.customDialogLayout);

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


вы можете использовать этот проект AlertDialogPro. Включите этот проект в свой и определите свою тему, как показано ниже:

<style name="YourAppTheme.AlertDialogProTheme" parent="AlertDialogProTheme.Holo.Light">
    <!-- Custom the title -->
    <item name="android:windowTitleStyle">@style/YourDialogWindowTitle</item>
    <!-- Change the title line to orange -->
    <item name="adpTitleDividerBackground">#E5492A</item>
</style>

<style name="YourDialogWindowTitle" parent="DialogWindowTitle.Holo.Light">
    <item name="android:textColor">#E5492A</item>
</style>

и укажите эту тему в тему вашего приложения с атрибутом "alertDialogProTheme":

<style name="AppTheme" parent="AppBaseTheme">
  ...
  <item name="alertDialogProTheme">@style/YourAppTheme.AlertDialogProTheme</item>
</style>

Используйте AlertDialogPro.Строитель для построения диалога:

AlertDialogPro.Builder builder = new AlertDialogPro.Builder(getContext());
builder.setTitle(R.string.app_name).
    setMessage("Message").
    setPositiveButton("Rate Now", null).
    setNeutralButton("Remind me later", null).
    setNegativeButton("No,thanks", null).
    show();

screenshot