Özel bildirim düzenleri ve metin renkleri


82

Uygulamam bazı bildirimler gösteriyor ve kullanıcı tercihlerine bağlı olarak bir bildirimde özel bir düzen kullanabilir. İyi çalışıyor, ancak küçük bir sorun var - metin renkleri . Stok Android ve hemen hemen tüm üretici dış görünümleri bildirim metni için açık renkli bir arka plana karşı siyah metin kullanır, ancak Samsung bunu yapmaz: bildirim açılır pencerelerinin koyu bir arka planı vardır ve varsayılan bildirim düzenindeki metin beyazdır.

Yani bu bir soruna neden oluyor: Süslü düzen kullanmayan bildirimler iyi görünüyor, ancak özel bir düzen kullananların okunması zor çünkü metin varsayılan beyaz yerine siyah. Resmi belgeler bile a #000için bir renk belirlediğinden TextView, orada herhangi bir işaretçi bulamadım.

Bir kullanıcı sorunun ekran görüntüsünü alacak kadar nazikti:

Ekran görüntüsü

Öyleyse , düzenlerimde aygıttan varsayılan bildirim metni rengini nasıl kullanırım ? Metin rengini telefon modeline göre dinamik olarak değiştirmeye başlamayı tercih ederim, çünkü bu çok fazla güncelleme gerektirir ve özel ROM'ları olan kişiler, kullandıkları dış görünüme bağlı olarak sorunu hala yaşayabilir.


10
resim artık mevcut değil
Amir Uval

Mümkünse lütfen resmi yeniden yükleyin.
Maciej Gol

Yanıtlar:


63

Malcolm'un çözümü API> = 9 ile sorunsuz çalışıyor. İşte eski API için çözüm:

İşin püf noktası, standart bildirim nesnesini oluşturmak ve ardından contentViewtarafından oluşturulan varsayılanı geçmek Notification.setLatestEventInfo(...). Doğru TextView'ı bulduğunuzda, sadece tv.getTextColors().getDefaultColor().

Varsayılan metin rengini ve metin boyutunu (ölçeklendirilmiş yoğunluk piksellerinde - sp) çıkaran kod aşağıda verilmiştir.

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

İe arayın extractColors. hizmetinizin onCreate () 'sinde. Ardından, özel bildirimi oluştururken, istediğiniz renk ve metin boyutu içindedir notification_text_colorve 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);

1
+1 harika yanıt. İyi çalışıyor. Başlık ve ana içerik için 2 farklı varsayılan renk olduğunu fark ettim. Her ikisini de getirmek istiyorum, ancak bu yöntemi kullanarak yalnızca başlık rengini alabildim - yineleme yalnızca 1 metin kutusu buluyor gibi görünüyor. Herhangi bir fikir?
Hermit

1
@Raw ile aynı şeyi görüyorum, yalnızca bir TextView. "Utest" i başka bir arama ipucuyla (ve farklı bir dizeyle) değiştirdim. Yalnızca bir TextView bulur ve COLOR_SEARCH_RECURSE_TIP ile eşleşir. Herhangi bir işaret var mı? Teşekkür.
ciscogambo

6
Yalnızca birini bulmasının nedeni, "return recurseGroup ((ViewGroup) gp.getChildAt (i));" içindeki bir hatadır; - yöntem yalnızca iç "recurseGroup" true döndürdüyse dönmelidir. Şöyle olmalıdır: "if (recurseGroup ((ViewGroup) gp.getChildAt (i))) true döndürür;". Çözüm için teşekkürler - kutudan çıkar çıkmaz harika bir düşünce.
AlikElzin-kilaka

9
Bu cevap için teşekkürler, çok yardımcı oldu. İlgilenen herkes için, Gaks cevabına göre hem başlığı hem de metin rengini / boyutunu almak için bırakılabilecek kadar hızlı bir ders verdim. Burada bulunabilir: pastebin.com/sk08QGxs
NuSkooler

3
Bunun nedeni bu cümlenin dikkat doğru değil (API düzeyinde 10 ile Galaxy Ace test): Solution by Malcolm works fine with API>=9. Biliyorsunuz, Android ve üreticiler aldatıcı bir şeydir. Her platform için bu çözümü kullanın.
cprcrack

83

Çözüm, yerleşik stilleri kullanmaktır. İhtiyaç duyduğunuz stile TextAppearance.StatusBar.EventContentAndroid 2.3 ve Android 4.x'te denir . Android'de 5.x malzeme bildirimleri diğer bazı stilleri kullanabilirsiniz: TextAppearance.Material.Notification, TextAppearance.Material.Notification.Title, ve TextAppearance.Material.Notification.Line2. Metin görünümü için uygun metin görünümünü ayarlamanız yeterlidir ve gerekli renkleri elde edersiniz.

Bu çözüme nasıl ulaştığımı merak ediyorsanız, işte benim ekmek kırıntılarım. Kod alıntıları Android 2.3'ten alınmıştır.

  1. Yerleşik Notificationaraçları kullanarak metni kullandığınızda ve ayarladığınızda, aşağıdaki satır düzeni oluşturur:

    RemoteViews contentView = new RemoteViews(context.getPackageName(),
            com.android.internal.R.layout.status_bar_latest_event_content);
    
  2. Söz konusu düzen, Viewbildirim metnini görüntülemekten sorumlu olan aşağıdakileri içerir :

    <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. Yani sonuç şudur ki, ihtiyaç duyulan stil TextAppearance.StatusBar.EventContent, hangi tanım şuna benzer:

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

    Burada, bu stilin aslında yerleşik renklerin hiçbirine atıfta bulunmadığını not etmelisiniz, bu nedenle en güvenli yol, bazı yerleşik renkler yerine bu stili uygulamaktır.

Bir şey daha: Android 2.3'ten (API Seviye 9) önce ne stil ne de renkler vardı, sadece sabit kodlanmış değerler vardı. Herhangi bir nedenle bu tür eski sürümleri desteklemeniz gerekiyorsa, Gaks'ın cevabına bakın .


Bu yanıtı anladığımı sanmıyorum. Son cümle, bunun için kullanılabilecek bir renk referansı olmadığını belirtir. Bu durumda hangi renk kullanılmalıdır?
Steve Pomeroy

Bununla birlikte, Android'in değişiklik günlüğünde, yalnızca API seviyesi 9'dan itibaren android: textAppearance = "@ androidstyle / TextAppearance.StatusBar.EventContent" öğesinin herkese açık hale getirildiğini fark ettim. Ondan önce gizliydi.
Steve Pomeroy

1
Android 2.3'ten önce gizli değildi, sadece mevcut değildi. O zamanlar düzende sabit kodlanmış bir değer vardı ve aygıt satıcısı bunu değiştirmeye karar verdiyse, bu konuda hiçbir şey yapamazsınız. Bu değere erişebileceğiniz hiçbir renk veya stil yoktu. Şu anda hala renk yok ama bu özel metin rengini elde etmek için uygulayabileceğiniz bir stiliniz var. Mantıklı olmak? :)
Malcolm

3
Hangi yerel tarz? Cevabımdaki stil doğrudan Android kaynağından alındı. Bunu herhangi bir yerleşik stil ( style="@android:style/TextAppearance.StatusBar.EventContent") gibi uygular ve metin için gerekli rengi alırsınız. Bu süper olacak #ff6b6b6bvanilya Android'in durumunda, ya da her türlü renk cihaz satıcı tarafından yerine orada kuruldu.
Malcolm

4
Başkalarının bilmesini sağlamak için, bu Android 6+ üzerinde çalışmaz
iGoDa

17

Yalnızca kaynakları kullanan herhangi bir SDK sürümü için çözüm burada.

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

Not: Sabit kodlu değerler 2.2- için kullanılmaktadır. Bu nedenle bazı nadir eski özel yazılımlarda sorunlar ortaya çıkabilir.


metin renginin gerekli olduğundan emin misiniz? ebeveyn zaten ayarlıyor, değil mi?
android geliştiricisi

13

2.3+ için ( Android belgelerinden ):

android:TextAppearance.StatusBar.EventContent.TitleBirincil metin için stili kullanın .

android:TextAppearance.StatusBar.EventContentİkincil metin için stili kullanın .

2.2- için, Gaks'ın bu konuya başka bir yanıtta önerdiği şeyi yapın .

2.2'ye karşı derlemek ve 2.3+ 'yi desteklemek ve mevcut tüm cihaz çeşitlerini desteklemek istiyorsanız, Gaks'ın çözümü bildiğim tek çözüm.

Google'ın ?android:attr/textColorPrimary2.2- değerini kullanma konusunda önerdiği BTW çalışmıyor. Sadece öykünücüyü kullanarak deneyin. Gaks'ın yolu tek yol.

Daha fazla kaynak: Bu ve bu çalışmıyor.


5
2.3+ talimatlarınız Android 5 için çalışmadı. Beyaz bir arka plan üzerinde beyaz metin oluşturdu.
Sam

6

Bunu söz konusu TextView'da kullanıyorum:

style="@style/TextAppearance.Compat.Notification.Title"

Arka plan siyahsa, arka plan beyazsa bana beyaz metin veriyor. Ve en azından API 19 kadar eskiden çalışır.


2

Belirtilen renkleri kullanmalısınız android.R.color

Örneğin: android.R.color.primary_text_light

Özel ROM geliştiricilerinin ve Android dış görünüm tasarımcılarının bunları güncellemesi beklenir, böylece uygulamanızın renkleri sistemin geri kalanıyla uyumlu olabilir. Bu, metninizin sistem genelinde düzgün bir şekilde görünmesini sağlamayı içerir.


Hangi rengi kullanmam gerekiyor android.R.color? Tüm metin renklerinin hem "koyu" hem de "açık" varyasyonları vardır.
Veeti

1
Özel teması olan bir cihazım yok, bu yüzden hangisini kullanacağımı gerçekten test edemiyorum. İkisini de deneyin ve hangisinin sizin için işe yaradığını görün.
Austyn Mahoney

1

Şu talimatlara bakın: http://developer.android.com/guide/topics/ui/notifiers/notifications.html#CustomExpandedView LinearLayout kapsayıcısı için arka plan renginizi ayarlarsanız, renklerinizi metin bildiriminde ve arkaplan.

Bildirim metninin varsayılan rengi başlatıcı uygulaması tarafından tanımlandıysa, başlatıcı bu bilgiyi paylaşmadığı sürece bunu android varsayılan ayarlarından alamazsınız.

Ancak, android: textColor = "# 000" satırını mizanpajınızdan kaldırmayı denediniz mi, böylece otomatik olarak varsayılan rengi alabilsin?


1
Metin rengini kaldırmak yardımcı olmaz - varsayılan, bildirim renkleriyle eşleşmez.
Veeti

Arka planı değiştirmeyi denediniz mi? Bunun ciddi bir sorun olduğunu düşünüyorum ve bu konuyu açmanız iyi oldu. Google geliştirici forumunu / gruplarını denediniz mi?
Lumis


1

Bunun eski bir soru olduğunu biliyorum ama başka birine yardımcı olabilir; ) Bunu uygulamamda yapıyorum ve bu birkaç satırda mükemmel çalışıyor:

    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

@Malckom'un çözümü, Lolipop'ta TextAppearance.Material.Notification.Title nedeniyle karanlık bildirim arka planıyla bana yardımcı olmadı. @Grzaks'ın çözümü yaptı, ancak bildirim oluşturma sürecinde bazı değişikliklerle:

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

İşte bu hatayı çözmek için benim için işe yarayan şey. Stiller.xml dosyasına aşağıdakileri ekleyin

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

0

Senin expanable veya collaspse düzen setinde android:backgroundbir şekilde "@android:color/transparent"bu çünkü otomatik arka plan olarak cihazınızın bildirim tema rengi ve dizi çekmek edilir

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="180dp"
android:layout_margin="0dp"
android:background="@android:color/transparent"
android:orientation="vertical">
          <TextView

            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textColor="@color/colorSecondary"
            android:textStyle="bold" />

Ve metin görünüm renginiz siyah ve beyazı Resource/colorbasit renkli dosyadaki ve gece modu renkli dosyadaki dosyadaki gibi tanımlar

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.