Bagaimana cara mengubah warna judul AlertDialog dan warna garis di bawahnya

109

Saya mengubah warna judul AlertDialog menggunakan perintah ini

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

Tapi saya ingin mengubah warna garis yang muncul di bawah judul; bagaimana saya bisa melakukan itu?

Catatan: Saya tidak ingin menggunakan tata letak khusus

tangkapan layar dari efek yang diinginkan

Mohammed Subhi Sheikh Quroush
sumber
1
adakah alasan khusus Anda ingin menghindari tata letak khusus? Ketentuan tambahan apa yang Anda miliki yang perlu dipenuhi?
Daniel Smith
4
Anda sebenarnya dapat mengubah warna judul AlertDialog dengan peretasan yang sangat sederhana. stackoverflow.com/a/21401181/855884
MatrixDev

Jawaban:

134

Sayangnya, ini bukanlah tugas yang mudah untuk diselesaikan. Dalam jawaban saya di sini , saya merinci cara menyesuaikan warna a ListSeparatordengan hanya memeriksa gaya induk yang digunakan oleh Android, membuat gambar baru, dan membuat gaya baru berdasarkan aslinya. Sayangnya, tidak seperti ListSeparatorgaya 's, AlertDialogtema bersifat internal, dan karena itu tidak dapat dirujuk sebagai gaya induk. Tidak ada cara mudah untuk mengubah garis biru kecil itu! Jadi, Anda perlu membuat dialog khusus.

Jika itu bukan secangkir teh Anda ... jangan menyerah! Saya sangat terganggu karena tidak ada cara mudah untuk melakukan ini, jadi saya menyiapkan proyek kecil di github untuk membuat dialog gaya holo yang dapat disesuaikan dengan cepat (dengan asumsi bahwa telepon mendukung gaya Holo). Anda dapat menemukan proyeknya di sini: https://github.com/danoz73/QustomDialog

Ini harus dengan mudah memungkinkan perubahan dari biru membosankan menjadi oranye menarik!

masukkan deskripsi gambar di sini

Proyek ini pada dasarnya adalah contoh penggunaan pembuat dialog khusus, dan dalam contoh saya membuat tampilan khusus yang sepertinya memenuhi contoh Alamat IP yang Anda berikan dalam pertanyaan asli Anda.

Dengan QustomDialog, untuk membuat dialog dasar (judul, pesan) dengan warna berbeda yang diinginkan untuk judul atau pembatas, Anda menggunakan kode berikut:

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

Dan untuk menambahkan tata letak khusus (katakanlah, untuk menambahkan alamat IP kecil EditText), Anda menambahkan

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

ke pembuat dengan tata letak yang telah Anda rancang (contoh IP dapat ditemukan di github). Saya harap ini membantu. Terima kasih banyak kepada Joseph Earl dan jawabannya di sini .

Daniel Smith
sumber
2
mengapa android masih belum mendukung pengubahan warna dialog peringatan, haruskah saya menggunakan dialog lain, atau di mana masalahnya?
Mohammed Subhi Sheikh Quroush
3
Android mungkin mencoba menerapkan pola UI yang konsisten, jadi kemungkinan itulah mengapa hal ini sangat menantang. Ini adalah solusi terbaik yang dapat saya buat untuk membantu Anda. Saya harap Anda merasa berguna, atau setidaknya menarik dan informatif :)
Daniel Smith
2
halo Daniel. Terimakasih telah membagi pekerjaanmu. Ini cukup membantu. Saya menghadapi satu masalah dalam menerapkan ini. Sebenarnya saya ingin menambahkan satu pilihan item menggunakan setItemsdalam dialog kustom ini. Ketika saya menambahkan daftar itu sebenarnya menggeser judul di bawah daftar. Bagaimana mengatasi masalah ini.
Dory
3
yah, mungkin belum cukup ... Saya menghadapi masalah judul di bawah daftar ... maaf.
dentex
1
@DanielSofa hai! Kerja bagus, tetapi apakah Anda menemukan solusi untuk 'judul di bawah daftar' seperti yang disebutkan di atas
Shirish Herwade
74

Warna pembatas:

Ini sedikit diretas, tetapi berfungsi dengan baik untuk saya dan berfungsi tanpa pustaka eksternal (setidaknya di 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));

Anda dapat menemukan lebih banyak id dialog di file alert_dialog.xml . Misalnya. android:id/alertTitleuntuk mengubah warna judul ...

UPDATE: Warna judul

Retas untuk mengubah warna judul:

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));
mmrmartin.dll
sumber
Bahkan di KitKat saya bertemu di android.util.AndroidRuntimeException: requestFeature() must be called before adding contentsini.
Konrad Reiche
Saya menggunakan potongan kode ini di banyak tempat di aplikasi saya dan di mana pun itu berfungsi dengan baik. Saya hanya tahu tentang masalah di DialogFragmentmana warna judul belum teridentifikasi android:id/alertTitletetapi saya tidak menemukan yang benar.
mmrmartin
2
@platzhirsch, di kelas DialogFragment kustom saya, saya menghindari masalah requestFeature () dengan menjalankan kode kustomisasi di onStart (). Anda dapat mengakses dialog di sana menggunakan getDialog ().
arlomedia
1
Sama seperti peringatan untuk pengguna mendatang yang mungkin menemukan ini; untuk beberapa alasan, ketika saya hanya menggunakan Dialog umum, saya harus menggunakan "title" sebagai nama pengenal saya, bukan "alertTitle". Tidak yakin apakah ini disebutkan di tempat lain tetapi hanya berpikir saya akan menambahkan sedikit saya dengan harapan dapat membantu: P
zgc7009
3
Saya mendapatkan NullPointerExceptiondisetTextColor()
Abhi
21

periksa ini berguna untuk Anda ...

public void setCustomTitle (View customTitleView)

Anda mendapatkan detail dari tautan berikut.

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" />

masukkan deskripsi gambar di sini

Tn. Sandy
sumber
Saya mencoba ini tetapi saya masih memiliki garis biru di bawah TextView saya
Mohammed Subhi Sheikh Quroush
saya punya beberapa kode. yang diletakkan di jawaban setelah "Edit". kamu coba ini.
Tn. Sandy
10

Ini akan mengatur warna untuk judul, ikon, dan pembatas. Terikat untuk berubah dengan versi Android baru.

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

Ingatlah untuk memanggil dialog.show () sebelum memanggil metode ini.

Jared Rummler
sumber
@Vlado, apakah Anda menggunakan appcompat? Jika demikian, ini mungkin tidak berhasil.
Jared Rummler
9

Dengan mengikuti kode sumber Dialog , saya menemukan bahwa Judul dihasilkan di Kelas MidWindowdengan menggembungkan dialog_title_holo.xmltata letak. jadi Id dari mTitleViewadalah titledan Id pembagi adalahtitleDivider .

kita dapat mengakses Id titlehanya denganandroid.R.id.title .

dan akses ke Id titleDivider olehResources.getSystem().getIdentifier("titleDivider","id", "android");

Kode terakhir yang saya gunakan untuk mengubah Arah judul dan mengubah warna adalah:

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));
mrd abd
sumber
Ini jawaban yang lengkap! Menggunakan android.R.id.title untuk mengganti judul juga!
Andreas Lymbouras
Jawaban yang bagus, banyak membantu saya! Saya harus mengubah: TextView mTitle = (TextView) findViewById (android.R.id.title); ke: TextView mTitle = (TextView) dialog.findViewById (android.R.id.title); agar ini berhasil.
Jan Ziesse
Yang ini berhasil untuk saya, saya menggunakan Aktivitas yang mewarisi @android: style / Theme.Dialog. Bisa menyesuaikan garis pembatas dan warna judul. +1
voghDev
4

Jika Anda tidak menginginkan "perpustakaan" untuk itu, Anda dapat menggunakan peretasan yang buruk ini:

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

Ini telah diuji dan bekerja pada 4.x; tidak diuji di bawah, tetapi jika memori saya bagus, seharusnya berfungsi untuk 2.x dan 3.x

Benjamin Vadon
sumber
Ini berfungsi dengan baik karena 4.xi belum mencoba yang lain, jadi saya akan memberi mereka mencoba dan mengonfirmasi
kandroidj
getDialog () memberi saya kesalahan "Metode getDialog () tidak ditentukan untuk jenis MainActivity" yang meminta saya untuk membuat metode
Zen
4

Di kelas onCreateView, saya meletakkan ini:

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 menautkan ke file colors.xml kami yang menyimpan semua warna. Juga d.setTitlemenyediakan cara hacky untuk mengatur warna judul.

lg365.dll
sumber
1

Jika Anda membuat Layout kustom untuk dialog peringatan

maka Anda dapat menambahkan seperti ini dengan mudah untuk mengubah warna

<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>
Janmejoy
sumber
1

Jika Anda menggunakan tata letak judul khusus maka Anda dapat menggunakannya seperti alertDialog.setCustomTitle(customTitle);

Contoh

Pada dialog penggunaan thread UI seperti:

 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>
Amol Wadekar
sumber
Saya ingin mengubah warna garis di dalam elips merah
Mohammed Subhi Sheikh Quroush
1

Berikut adalah solusi lain (berdasarkan jawaban yang disarankan) yang menangani gaya dialog di satu kelas tanpa perlu mengkhawatirkan status dialog saat Anda mengubah gaya - dialog sudah dapat ditampilkan atau baru saja diinisialisasi.

Contoh penggunaan:

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

Penerapan:

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);
    }
}}
GMan
sumber
0

Melanjutkan dari jawaban ini: https://stackoverflow.com/a/15285514/1865860 , saya membagi repo github yang bagus dari @ daniel-smith dan membuat beberapa perbaikan:

  • Peningkatan Contoh Kegiatan
  • tata letak yang ditingkatkan
  • tetap setItemsmetode
  • menambahkan pemisah menjadi items_list
  • tutup dialog saat diklik
  • dukungan untuk item yang dinonaktifkan dalam setItemsmetode
  • listItem sentuh umpan balik
  • pesan dialog yang dapat digulir

tautan: https://github.com/dentex/QustomDialog

dentex
sumber
0

Daripada menggunakan pembagi dalam dialog, gunakan tampilan dalam tata letak khusus dan setel tata letak sebagai tata letak khusus dalam dialog.

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();
}
Velayutham M
sumber
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)
Samet ÖZTOPRAK
sumber
-1

Jika Anda menggunakan memperluas dialog, gunakan:

requestWindowFeature(Window.FEATURE_NO_TITLE);
Mahesh
sumber