Як я можу змінити колір заголовка AlertDialog та колір рядка під ним


109

Я змінив колір заголовка AlertDialog за допомогою цієї команди

alert.setTitle( Html.fromHtml("<font color='#FF7F27'>Set IP Address</font>"));

Але я хочу змінити колір рядка, який з’являється під заголовком; як я можу це зробити?

Примітка. Я не хочу використовувати спеціальний макет

скріншот потрібного ефекту


1
Чи є конкретна причина, яку ви хочете уникати спеціальних макетів? Які додаткові умови у вас є, що потрібно виконати?
Даніель Сміт

4
Ви можете фактично змінити колір заголовка AlertDialog дуже простим злом. stackoverflow.com/a/21401181/855884
MatrixDev

Відповіді:


134

На жаль, це завдання не дуже просте. У своїй відповіді тут я детально розповідаю, як налаштувати колір асистента ListSeparator, просто перевіривши батьківський стиль, який використовує Android, створивши нове зображення та створивши новий стиль на основі оригіналу. На жаль, на відміну від ListSeparatorстилю ', AlertDialogтеми є внутрішніми, і тому їх не можна позначати як батьківські стилі. Немає простого способу змінити цю маленьку синю лінію! Таким чином, вам потрібно вдатися до створення власних діалогів.

Якщо це просто не ваша чашка чаю ... не здавайся! Мене дуже занепокоїло, що не існує простого способу зробити це, тому я створив невеликий проект на github для створення швидко налаштованих діалогів у стилі холо (якщо припустити, що телефон підтримує стиль Holo). Ви можете знайти проект тут: https://github.com/danoz73/QustomDialog

Це має легко забезпечити перехід від нудного синього до захоплюючого помаранчевого!

введіть тут опис зображення

В основному проект є прикладом використання користувальницького конструктора діалогів, і в прикладі я створив спеціальний вид, який, здається, задовольняє прикладу IP-адреси, який ви даєте в своєму початковому запитанні.

З QustomDialog, для того , щоб створити основний діалог (заголовок, повідомлення) з необхідним різним кольором для заголовка або дільника, можна використовувати наступний код:

private String HALLOWEEN_ORANGE = "#FF7F27";

QustomDialogBuilder qustomDialogBuilder = new QustomDialogBuilder(v.getContext()).
    setTitle("Set IP Address").
    setTitleColor(HALLOWEEN_ORANGE).
    setDividerColor(HALLOWEEN_ORANGE).
    setMessage("You are now entering the 10th dimension.");

qustomDialogBuilder.show();

А для того, щоб додати нестандартний макет (скажімо, щоб додати маленьку IP-адресу EditText), ви додасте

setCustomView(R.layout.example_ip_address_layout, v.getContext())

до будівельника з розробленим вами макетом (приклад IP можна знайти в github). Я сподіваюся, що це допомагає. Велике спасибі Джозефу графу та його відповіді тут .


2
чому андроїд все ще не підтримує зміну кольорів діалогового вікна попередження, чи потрібно використовувати інше діалогове вікно, або де проблема?
Мухаммед Субхі Шейх Куроуш

3
Android, ймовірно, намагається застосувати послідовні зразки інтерфейсу користувача, тому, ймовірно, це так складно. Це найкраще рішення, яке я міг би створити, щоб допомогти вам. Сподіваюся, вам це стане корисним чи, принаймні, цікавим та інформативним :)
Daniel Smith

2
привіт Даніель. дякую за те, що поділилися вашою роботою. Це дуже корисно. Я зіткнувся з однією проблемою в реалізації цього. Насправді я хочу додати вибір одного елемента за допомогою setItemsцього спеціального діалогового вікна. Коли я додаю список, він фактично зміщує заголовок під списком. Як вирішити цю проблему.
Дорі

3
ну, можливо, ще не зовсім ... Я стикаюся з проблемою назви під списком ... вибачте.
дентекс

1
@DanielSmith привіт! Хороша робота, але чи знайшли ви рішення для "заголовка під списком", як згадувалося вище
Shirish Herwade

74

Колір роздільника:

Це трохи хак, але він чудово працює для мене, і він працює без жодної зовнішньої бібліотеки (принаймні на Android 4.4).

AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.dialog)
       .setIcon(R.drawable.ic)
       .setMessage(R.string.dialog_msg);
//The tricky part
Dialog d = builder.show();
int dividerId = d.getContext().getResources().getIdentifier("android:id/titleDivider", null, null);
View divider = d.findViewById(dividerId);
divider.setBackgroundColor(getResources().getColor(R.color.my_color));

Ви можете знайти більше ідентифікаторів діалогового вікна у файлі alar_dialog.xml . Напр. android:id/alertTitleдля зміни кольору заголовка ...

ОНОВЛЕННЯ: Колір заголовка

Хак для зміни кольору заголовка:

int textViewId = d.getContext().getResources().getIdentifier("android:id/alertTitle", null, null);
TextView tv = (TextView) d.findViewById(textViewId);
tv.setTextColor(getResources().getColor(R.color.my_color));

Навіть на KitKat я наткнувся android.util.AndroidRuntimeException: requestFeature() must be called before adding contentсюди.
Конрад Рейче

Я використовую цей фрагмент коду в багатьох місцях у моєму додатку, і він працює добре. Я знаю лише про проблеми, DialogFragmentде колір заголовка не ідентифікував, android:id/alertTitleале я не знайшов правильного.
mmrmartin

2
@platzhirsch, в моєму користувальницькому класі DialogFragment я уникнув проблеми requestFeature (), запустивши код налаштування в onStart (). Ви можете отримати доступ до діалогового вікна там за допомогою getDialog ().
арломедія

1
Так само, як голова для майбутніх користувачів, які можуть натрапити на це; чомусь, коли я використовую лише загальний діалог, я повинен використовувати "title" як своє ім'я ідентифікатора замість "alerTitle". Не впевнений, чи згадується це де-небудь ще, але я просто подумав, що я додам свій бит, сподіваючись допомогти: P
zgc7009

3
Я потрапляю NullPointerExceptionвsetTextColor()
Абхі

21

перевірте це корисно для вас ...

public void setCustomTitle (View customTitleView)

Ви отримуєте детальну інформацію за наступним посиланням.

http://developer.android.com/reference/android/app/AlertDialog.Builder.html#setCustomTitle%28android.view.View%29

CustomDialog.java

Dialog alert = new Dialog(this);
    alert.requestWindowFeature(Window.FEATURE_NO_TITLE);
    alert.setContentView(R.layout.title);
    TextView msg = (TextView)alert.findViewById(R.id.textView1);
    msg.setText("Hello Friends.\nIP address : 111.111.1.111");
    alert.show();

title.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" >

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Set IP address"
    android:textColor="#ff0000"
    android:textAppearance="?android:attr/textAppearanceLarge" />

<ImageView 
    android:layout_width="fill_parent"
    android:layout_height="2dp"
    android:layout_marginTop="5dp"
    android:background="#00ff00"
    />
<TextView
    android:id="@+id/textView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="#775500"
    android:textAppearance="?android:attr/textAppearanceLarge" />

введіть тут опис зображення


Я спробую це, але у мене все ще є синя лінія під моїм TextView
Мухаммед Субхі Шейх Куруш

у мене є код. які відповіли після "Правки". ти спробуй це.
Mr.Sandy

10

Це встановить колір заголовка, піктограми та роздільника. Змінний для зміни будь-якої нової версії Android.

public static void colorAlertDialogTitle(AlertDialog dialog, int color) {
    int dividerId = dialog.getContext().getResources().getIdentifier("android:id/titleDivider", null, null);
    if (dividerId != 0) {
        View divider = dialog.findViewById(dividerId);
        divider.setBackgroundColor(color);
    }

    int textViewId = dialog.getContext().getResources().getIdentifier("android:id/alertTitle", null, null);
    if (textViewId != 0) {
        TextView tv = (TextView) dialog.findViewById(textViewId);
        tv.setTextColor(color);
    }

    int iconId = dialog.getContext().getResources().getIdentifier("android:id/icon", null, null);
    if (iconId != 0) {
        ImageView icon = (ImageView) dialog.findViewById(iconId);
        icon.setColorFilter(color);
    }
}

Не забудьте зателефонувати dialog.show () перед тим, як викликати цей метод.


@Vlado ви використовуєте appcompat? Якщо так, це може не спрацювати.
Джаред Румлер

9

Дотримуючись вихідного коду Діалог , я виявив, що заголовок генерується у класі MidWindowшляхом надуття dialog_title_holo.xmlмакета. тож Id of mTitleViewє, titleа роздільник Id titleDivider.

ми можемо отримати доступ до Id titleпросто за допомогою android.R.id.title.

і доступ до ідентифікатора titleDividerпоResources.getSystem().getIdentifier("titleDivider","id", "android");

Остаточний код, який я використав для зміни Напряму заголовка та зміни кольору:

TextView mTitle = (TextView)findViewById(android.R.id.title);
mTitle.setGravity(Gravity.RIGHT|Gravity.CENTER_VERTICAL);
int x = Resources.getSystem().getIdentifier("titleDivider","id", "android");
View titleDivider = findViewById(x);
titleDivider.setBackgroundColor(getContext().getResources().getColor(R.color.some_color));

Це повна відповідь! Використовуючи android.R.id.title, щоб змінити назву!
Andreas Lymbouras

Чудова відповідь, мені дуже допомогли! Мені довелося змінити: TextView mTitle = (TextView) findViewById (android.R.id.title); до: TextView mTitle = (TextView) діалог.findViewById (android.R.id.title); щоб це працювало.
Jan Ziesse

Цей працював для мене, я використовую активність, яка успадковує @android: style / Theme.Dialog. Не вдалося налаштувати лінію роздільника та колір заголовка. +1
voghDev

4

Якщо ви не хочете "бібліотеки" для цього, ви можете скористатися цим злому:

((ViewGroup)((ViewGroup)getDialog().getWindow().getDecorView()).getChildAt(0)) //ie LinearLayout containing all the dialog (title, titleDivider, content)
.getChildAt(1) // ie the view titleDivider
.setBackgroundColor(getResources().getColor(R.color.yourBeautifulColor));

Це було випробувано та працювали на 4.x; не перевіряється, але якщо моя пам'ять хороша, вона повинна працювати для 2.x та 3.x


Це чудово працює для 4.xi, також не пробував інших, тому я спробую їх підтвердити
kandroidj

getDialog () дає мені помилку "Метод getDialog () не визначений для типу MainActivity", він просить мене створити метод
Дзен,

4

У класі onCreateView я ставлю це:

Dialog d = getDialog();
    d.setTitle(Html.fromHtml("<font color='#EC407A'>About</font>"));
    int dividerId = d.getContext().getResources().getIdentifier("android:id/titleDivider", null, null);
    View divider = d.findViewById(dividerId);
    divider.setBackgroundColor(getResources().getColor(R.color.colorPrimary));

colorPrimary посилання на наш color.xml файл, який зберігає всі кольори. Також d.setTitleнадається хакітний спосіб встановити колір заголовка.


1

Якщо ви створюєте власну розкладку для діалогового вікна попередження

тоді ви можете легко додати такий спосіб, щоб змінити колір

<LinearLayout
    android:id="@+id/DialogTitleBorder"
    android:layout_width="fill_parent"
    android:layout_height="1dip"
    android:layout_below="@id/mExitDialogDesc"
    android:background="#4BBAE3"            <!--change color easily -->
    >

</LinearLayout>

1

Якщо ви використовуєте спеціальний макет заголовка, ви можете використовувати його як alertDialog.setCustomTitle(customTitle);

Приклад

У діалоговому вікні використання інтерфейсу користувача, наприклад:

 LayoutInflater inflater = LayoutInflater.from(getApplicationContext());
 View customTitle = inflater.inflate(R.layout.customtitlebar, null);
 AlertDialog.Builder d = new AlertDialog.Builder(this);
 d.setCustomTitle(customTitle);
 d.setMessage("Message");
 d.setNeutralButton("OK", null);
 d.show();

customtitlebar.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="wrap_content"
    android:orientation="vertical"
    android:background="#525f67">

    <ImageView
        android:id="@+id/icon"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:src="@drawable/ic_launcher"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true" >
    </ImageView>

    <TextView
        android:id="@+id/customtitlebar"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:textColor="#ffffff"
        android:text="Title Name"
        android:padding="3px"
        android:textStyle="bold" 
        android:layout_toRightOf="@id/icon"
        android:layout_alignParentTop="true"
        android:gravity="center_vertical"/>

     <ImageView
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:background="#ff0000" 
        android:layout_below="@id/icon"><!-- This is line below the title -->
    </ImageView>

</RelativeLayout>

Я хочу змінити колір лінії всередині червоного еліпса
Mohammed Subhi Sheikh Quroush

1

Ось ще одне рішення (засноване на запропонованих відповідях), яке обробляє стилі діалогів в одному класі без необхідності турбуватися про стан діалогу при зміні стилю - діалог може бути вже показаний або просто ініціалізований.

Приклад використання:

AlertDialog.Builder builder = new AlertDialog.Builder(context);
AlertDialog dialog = builder.create(); //or builder.show()
DialogViewDecorator.decorate(dialog, android.R.color.holo_red_light); //can also set the defaut color in the class

Впровадження:

public class DialogViewDecorator {

private static final
@ColorRes int DEFAULT_TITLE_DIVIDER_COLOR = android.R.color.holo_orange_light;

public static void decorate(Dialog dialog) {
    decorate(dialog, DEFAULT_TITLE_DIVIDER_COLOR);
}

/**
 * Sets the title divider color when the view is shown by setting DialogInterface.OnShowListener on the dialog.
 * <p/>
 * If you want to do other things onShow be sure to extend OnDecoratedDialogShownListener(call super.show(...)!)
 * and call {@link #decorate(Dialog, int, OnDecoratedDialogShownListener)}.
 *
 * @param dialog
 * @param titleDividerColor
 */
public static void decorate(Dialog dialog, final int titleDividerColor) {
    decorate(dialog, titleDividerColor, new OnDecoratedDialogShownListener(titleDividerColor));
}

/**
 * Method for setting a extended implementation of OnDecoratedDialogShownListener. Don't forget to call super
 * or the titleDividerColor wont be applied!
 *
 * @param dialog
 * @param titleDividerColor
 * @param OnShowListener
 * @param <T>
 */
public static <T extends OnDecoratedDialogShownListener> void decorate(Dialog dialog, int titleDividerColor, T OnShowListener) {
    if (dialog == null || titleDividerColor <= 0) { return; }

    if (dialog.isShowing()) {
        setTitleDividerColor(dialog, titleDividerColor);
    } else {
        dialog.setOnShowListener(OnShowListener);
    }
}

private static void setTitleDividerColor(DialogInterface dialogInterface, int titleDividerColor) {
    try {
        Dialog dialog = (Dialog) dialogInterface;
        int dividerId = dialog.getContext().getResources().getIdentifier("android:id/titleDivider", null, null);
        View divider = dialog.findViewById(dividerId);
        if (divider != null) {
            divider.setBackgroundColor(dialog.getContext().getResources().getColor(titleDividerColor));
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}


public static class OnDecoratedDialogShownListener implements DialogInterface.OnShowListener {
    private int titleDividerColor;

    public OnDecoratedDialogShownListener() {
        this.titleDividerColor = DEFAULT_TITLE_DIVIDER_COLOR;
    }

    public OnDecoratedDialogShownListener(int titleDividerColor) {
        this.titleDividerColor = titleDividerColor;
    }

    @Override
    public void onShow(DialogInterface dialogInterface) {
        setTitleDividerColor(dialogInterface, titleDividerColor);
    }
}}

0

Продовжуючи цю відповідь: https://stackoverflow.com/a/15285514/1865860 , я відправив чудове репо з github від @ daniel-smith і вніс декілька вдосконалень:

  • покращений приклад Діяльність
  • покращені плани
  • фіксований setItemsметод
  • додано роздільники в items_list
  • відхилити діалоги при натисканні
  • підтримка відключених елементів у setItemsметодах
  • listItem зворотній зв'язок
  • діалогове повідомлення, що прокручується

посилання: https://github.com/dentex/QustomDialog


0

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

custom_popup.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">

    <com.divago.view.TextViewMedium
        android:id="@+id/txtTitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:paddingBottom="10dp"
        android:paddingTop="10dp"
        android:text="AlertDialog"
        android:textColor="@android:color/black"
        android:textSize="20sp" />

    <View
        android:id="@+id/border"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_below="@id/txtTitle"
        android:background="@color/txt_dark_grey" />

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/border"
        android:scrollbars="vertical">

        <com.divago.view.TextViewRegular
            android:id="@+id/txtPopup"
            android:layout_margin="15dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </ScrollView>
</RelativeLayout>

Activity.java:

public void showPopUp(String title, String text) {

    LayoutInflater inflater = getLayoutInflater();
    View alertLayout = inflater.inflate(R.layout.custom_popup, null);

    TextView txtContent = alertLayout.findViewById(R.id.txtPopup);
    txtContent.setText(text);

    TextView txtTitle = alertLayout.findViewById(R.id.txtTitle);
    txtTitle.setText(title);

    AlertDialog.Builder alert = new AlertDialog.Builder(this);
    alert.setView(alertLayout);
    alert.setCancelable(true);

    alert.setPositiveButton("Done", new DialogInterface.OnClickListener() {

        @Override
        public void onClick(DialogInterface dialog, int which) {
            dialog.dismiss();
        }
    });

    AlertDialog dialog = alert.create();
    dialog.show();
}

0
    ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(Color.BLACK);

    String title = context.getString(R.string.agreement_popup_message);
    SpannableStringBuilder ssBuilder = new SpannableStringBuilder(title);
    ssBuilder.setSpan(
            foregroundColorSpan,
            0,
            title.length(),
            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
    );

AlertDialog.Builder alertDialogBuilderUserInput = new AlertDialog.Builder(context);
alertDialogBuilderUserInput.setTitle(ssBuilder)

-1

Якщо ви використовуєте розширення діалогового вікна, використовуйте:

requestWindowFeature(Window.FEATURE_NO_TITLE);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.