Pertanyaan Tata letak pemberitahuan khusus dan warna teks


Aplikasi saya menampilkan beberapa notifikasi, dan bergantung pada preferensi pengguna, itu mungkin menggunakan tata-letak khusus dalam pemberitahuan. Ini bekerja dengan baik, tetapi ada masalah kecil - warna teks. Bursa Android dan hampir semua produsen kulit menggunakan teks hitam dengan latar belakang terang untuk teks pemberitahuan, tetapi Samsung tidak: pulldown pemberitahuan mereka memiliki latar belakang gelap dan teks di tata letak pemberitahuan default berwarna putih.

Jadi ini menyebabkan masalah: pemberitahuan yang tidak menggunakan tata letak mewah tampil bagus, tetapi yang menggunakan tata letak khusus sulit dibaca karena teksnya berwarna hitam daripada putih default. Bahkan itu dokumentasi resmi set saja a #000 warna untuk a TextView, jadi saya tidak bisa menemukan petunjuk di sana.

Seorang pengguna cukup baik untuk mengambil tangkapan layar masalah:

Screenshot

Begitu bagaimana cara menggunakan warna teks pemberitahuan default dari perangkat di layout saya? Saya lebih suka tidak memulai mengubah warna teks secara dinamis berdasarkan model ponsel, karena itu membutuhkan banyak pembaruan dan orang-orang dengan ROM khusus mungkin masih mendapatkan masalah, tergantung pada kulit yang mereka gunakan.


75
2018-02-01 19:57


asal


Jawaban:


Solusi oleh Malcolm berfungsi dengan baik dengan API> = 9. Inilah solusi untuk API yang lebih lama:

Triknya adalah membuat objek pemberitahuan standar dan kemudian melintasi default contentView dibuat oleh Notification.setLatestEventInfo(...). Ketika Anda menemukan TextView yang tepat, cukup dapatkan tv.getTextColors().getDefaultColor().

Berikut kode yang mengekstrak warna teks dan ukuran teks default (dalam skala kepadatan piksel - sp).

private Integer notification_text_color = null;
private float notification_text_size = 11;
private final String COLOR_SEARCH_RECURSE_TIP = "SOME_SAMPLE_TEXT";

private boolean recurseGroup(ViewGroup gp)
{
    final int count = gp.getChildCount();
    for (int i = 0; i < count; ++i)
    {
        if (gp.getChildAt(i) instanceof TextView)
        {
            final TextView text = (TextView) gp.getChildAt(i);
            final String szText = text.getText().toString();
            if (COLOR_SEARCH_RECURSE_TIP.equals(szText))
            {
                notification_text_color = text.getTextColors().getDefaultColor();
                notification_text_size = text.getTextSize();
                DisplayMetrics metrics = new DisplayMetrics();
                WindowManager systemWM = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
                systemWM.getDefaultDisplay().getMetrics(metrics);
                notification_text_size /= metrics.scaledDensity;
                return true;
            }
        }
        else if (gp.getChildAt(i) instanceof ViewGroup)
            return recurseGroup((ViewGroup) gp.getChildAt(i));
    }
    return false;
}

private void extractColors()
{
    if (notification_text_color != null)
        return;

    try
    {
        Notification ntf = new Notification();
        ntf.setLatestEventInfo(this, COLOR_SEARCH_RECURSE_TIP, "Utest", null);
        LinearLayout group = new LinearLayout(this);
        ViewGroup event = (ViewGroup) ntf.contentView.apply(this, group);
        recurseGroup(event);
        group.removeAllViews();
    }
    catch (Exception e)
    {
        notification_text_color = android.R.color.black;
    }
}

Panggilan extractColors yaitu. di onCreate () dari layanan Anda. Lalu saat Anda membuat pemberitahuan khusus, warna dan ukuran teks yang Anda inginkan ada di dalamnya notification_text_color dan notification_text_size:

Notification notification = new Notification();
RemoteViews notification_view = new RemoteViews(getPackageName(), R.layout.notification);       
notification_view.setTextColor(R.id.label, notification_text_color);
notification_view.setFloat(R.id.label, "setTextSize", notification_text_size);

57
2017-09-06 13:21



Solusinya adalah menggunakan gaya bawaan. Gaya yang Anda butuhkan disebut TextAppearance.StatusBar.EventContent di Android 2.3 dan Android 4.x. Di Android pemberitahuan material 5.x menggunakan beberapa gaya lain: TextAppearance.Material.Notification, TextAppearance.Material.Notification.Title, dan TextAppearance.Material.Notification.Line2. Cukup mengatur tampilan teks yang sesuai untuk tampilan teks, dan Anda akan mendapatkan warna yang diperlukan.

Jika Anda tertarik bagaimana saya sampai pada solusi ini, inilah jejak remah roti saya. Kutipan kode diambil dari Android 2.3.

  1. Ketika Anda menggunakan Notification dan mengatur teks dengan menggunakan sarana bawaan, baris berikut membuat tata letak:

    RemoteViews contentView = new RemoteViews(context.getPackageName(),
            com.android.internal.R.layout.status_bar_latest_event_content);
    
  2. Tata letak yang disebutkan mengandung hal-hal berikut View yang bertanggung jawab untuk melihat teks pemberitahuan:

    <TextView android:id="@+id/text"
        android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:singleLine="true"
        android:ellipsize="marquee"
        android:fadingEdge="horizontal"
        android:paddingLeft="4dp"
        />
    
  3. Jadi kesimpulannya adalah gaya yang dibutuhkan adalah TextAppearance.StatusBar.EventContent, definisi mana yang terlihat seperti ini:

    <style name="TextAppearance.StatusBar.EventContent">
        <item name="android:textColor">#ff6b6b6b</item>
    </style>
    

    Anda harus mencatat di sini bahwa gaya ini tidak benar-benar mengacu pada warna yang ada di dalamnya, jadi cara paling aman adalah menerapkan gaya ini daripada warna yang sudah ada.

Satu hal lagi: sebelum Android 2.3 (API Level 9), tidak ada gaya, atau warna, hanya ada nilai-nilai hard-coded. Jika Anda harus mendukung versi lama tersebut untuk beberapa alasan, lihat dijawab oleh Gaks .


80
2018-02-08 15:50



Berikut ini solusi untuk setiap versi SDK yang hanya menggunakan sumber daya.

res / values ​​/ styles.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="NotificationTitle">
      <item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
      <item name="android:textStyle">bold</item>
    </style>
    <style name="NotificationText">
      <item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
    </style>
</resources>

res / values-v9 / styles.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="NotificationText" parent="android:TextAppearance.StatusBar.EventContent" />
    <style name="NotificationTitle" parent="android:TextAppearance.StatusBar.EventContent.Title" />
</resources>

res / layout / my_notification.xml

...
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="title"
    style="@style/NotificationTitle"
    />
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="text"
    style="@style/NotificationText"
    />
...

P.S: Nilai berkode keras digunakan untuk 2.2-. Jadi masalah dapat terjadi dengan beberapa perangkat lunak kebiasaan lama yang langka.


16
2018-01-06 04:58



Untuk 2.3+ (Dari Dokumentasi Android):

Gunakan gaya android:TextAppearance.StatusBar.EventContent.Title untuk teks utama.

Gunakan gaya android:TextAppearance.StatusBar.EventContent untuk teks sekunder.

Untuk 2.2-, lakukan apa Gaks menyarankan di jawaban lain untuk utas ini.

Jika Anda ingin mengkompilasi terhadap 2.2 dan mendukung 2.3+, dan mendukung semua variasi perangkat di luar sana, solusi Gaks adalah satu-satunya yang saya tahu.

BTW, apa yang disarankan Google tentang menggunakan nilai ?android:attr/textColorPrimary untuk 2.2-, tidak berfungsi. Coba saja menggunakan emulator. Cara Gaks adalah satu-satunya cara.

Lebih banyak sumber daya: Ini dan ini tidak bekerja.


13
2017-12-06 19:21



Anda harus menggunakan warna yang ditentukan dalam android.R.color

Sebagai contoh: android.R.color.primary_text_light

Pengembang ROM kustom dan perancang kulit Android seharusnya memperbarui ini sehingga warna aplikasi Anda dapat sejalan dengan sistem lainnya. Ini termasuk memastikan teks Anda muncul dengan benar di seluruh sistem.


2
2018-02-02 02:40



Saya telah menemukan solusi yang sangat sederhana yang langsung mengubah nama atribut yang disediakan oleh Android.

Seperti yang bisa Anda lihat dalam tutorial ini: http://www.framentos.com/android-tutorial/2012/02/20/how-to-create-a-custom-notification-on-android/

Anda hanya perlu menggunakan atribut yang berbeda:

<item name="android:textColor">?android:attr/textColorPrimaryInverse</item>

Semoga ini bisa membantu Anda!


2
2018-02-21 18:49



Lihatlah instruksi ini: http://developer.android.com/guide/topics/ui/notifiers/notifications.html#CustomExpandedView  Jika Anda mengatur warna latar belakang untuk wadah LinearLayout maka Anda dapat memiliki warna Anda dalam pemberitahuan untuk teks dan latar belakang.

Jika warna default untuk teks pemberitahuan ditentukan oleh aplikasi peluncur, maka Anda tidak dapat mengambilnya dari pengaturan default android kecuali peluncur meng-sharring informasi ini.

Namun, sudahkah Anda mencoba menghapus baris ini android: textColor = "# 000" dari tata letak Anda sehingga bisa mendapatkan warna default secara otomatis?


1
2018-02-06 05:34



Solusi dari @Malckom tidak membantu saya di Lolipop dengan latar belakang pemberitahuan gelap karena TextAppearance.Material.Notification.Title adalah warna sistem hardcoded. Solusi dari @grzaks melakukannya, tetapi dengan beberapa perubahan dalam proses pembuatan notifikasi:

NotificationCompat.Builder mBuilder =
    new NotificationCompat.Builder(this)
                          .setContentTitle(NOTIFICATION_TITLE_TIP)
                          .setContentText(NOTIFICATION_TEXT_TIP);
Notification ntf = mBuilder.build();
// ...
if (NOTIFICATION_TEXT_TIP.equals(szText)) {
    notification_text_color = text.getTextColors().getDefaultColor();
} else {
    if (NOTIFICATION_TITLE_TIP.equals(szText)) {
        notification_title_color = text.getTextColors().getDefaultColor();
    }
}
// ...

0
2018-03-05 12:51



Saya tahu ini pertanyaan lama tetapi bisa membantu orang lain; ) Saya melakukan ini di aplikasi saya dan itu berfungsi sempurna dalam beberapa baris:

    RemoteViews notificationView = new RemoteViews(context.getPackageName(), R.layout.notification_layout);

    if (SDK >= LOLLIPOP) {

            TextView textView = new TextView(context);
            textView.setTextAppearance(context, android.R.style.TextAppearance_Material_Notification_Title);

            notificationView.setTextColor(R.id.title, textView.getCurrentTextColor());
            notificationView.setFloat(R.id.title, "setTextSize", textView.getTextSize());

            textView.setTextAppearance(context,android.R.style.TextAppearance_Material_Notification_Line2);

            notificationView.setTextColor(R.id.contentText,textView.getCurrentTextColor());
            notificationView.setFloat(R.id.contentText,"setTextSize",textView.getTextSize());

            textView = null;

    }

0
2018-01-01 22:38