Niestandardowe układy powiadomień i kolory tekstu

Moja aplikacja wyświetla niektóre powiadomienia i w zależności od preferencji użytkownika może używać niestandardowego układu w powiadomieniu. Działa dobrze, ale jest mały problem --kolory tekstu . Zdjęcie Android i prawie wszystkie skórki producenta używać czarny tekst na jasnym tle dla tekstu powiadomienia, ale Samsung Nie: ich pulldown powiadomienia ma ciemne tło i tekst w domyślnym układzie powiadomień jest biały.

Więc to powoduje problem: powiadomienia które nie używają żadnych wymyślnych układów wyświetlają się dobrze, ale ten, który używa układu niestandardowego, jest trudny do odczytania, ponieważ tekst jest czarny zamiast domyślnego białego. Nawet oficjalna dokumentacja ustawia #000 kolor dla TextView, więc nie mogłem znaleźć tam żadnych wskaźników.

Użytkownik był na tyle uprzejmy, aby zrobić zrzut ekranu problemu:

Zrzut ekranu

Więc Jak używać domyślnego koloru tekstu powiadomienia z urządzenia w moich układach? Wolałabym nie zaczynać. dynamiczna zmiana Koloru tekstu w oparciu o model telefonu, ponieważ wymaga to wielu aktualizacji, a osoby z niestandardowymi ROM-AMI mogą nadal mieć problem, w zależności od używanej Skórki.

Author: erdemlal, 2011-02-01

10 answers

Solution by Malcolm działa dobrze z API> = 9. Oto rozwiązanie dla starszego API:

Sztuką jest utworzenie standardowego obiektu powiadomień, a następnie przejście do domyślnego contentView utworzonego przez Notification.setLatestEventInfo(...). Kiedy znajdziesz odpowiedni TextView, po prostu pobierz tv.getTextColors().getDefaultColor().

Oto kod, który wyodrębnia domyślny kolor i rozmiar tekstu (w skalowanych pikselach gęstości-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;
    }
}

Call extractColors ie. in onCreate () of your service. Następnie podczas tworzenia niestandardowego powiadomienia, kolor i rozmiar tekstu, który chcesz są w notification_text_color i 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
Author: grzaks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-06 13:21:42

Rozwiązaniem jest użycie wbudowanych stylów. Styl, którego potrzebujesz, nazywa się TextAppearance.StatusBar.EventContent w Androidzie 2.3 i Androidzie 4.x. w Androidzie 5.powiadomienia o materiałach x używają kilku innych stylów: TextAppearance.Material.Notification, TextAppearance.Material.Notification.Title, i TextAppearance.Material.Notification.Line2. Wystarczy ustawić odpowiedni wygląd tekstu dla widoku tekstu, a otrzymasz niezbędne kolory.

Jeśli jesteś zainteresowany, jak doszedłem do tego rozwiązania, oto mój ślad bułki tartej. Fragmenty kodu pochodzą z Androida 2.3.

  1. Kiedy używasz Notification i ustawić tekst za pomocą wbudowanych środków, następujący wiersz tworzy układ:

    RemoteViews contentView = new RemoteViews(context.getPackageName(),
            com.android.internal.R.layout.status_bar_latest_event_content);
    
  2. Wspomniany układ zawiera następujący View, który jest odpowiedzialny za wyświetlanie tekstu powiadomienia:

    <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. Więc wniosek jest taki, że potrzebny styl to TextAppearance.StatusBar.EventContent, którego definicja wygląda tak:

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

    Należy zauważyć, że ten styl nie odnosi się do żadnego z wbudowanych kolorów, więc najbezpieczniejszym sposobem jest zastosowanie tego stylu jakiegoś wbudowanego koloru.

Jeszcze jedno: przed Androidem 2.3 (poziom API 9) nie było ani stylów, ani kolorów, były tylko wartości zakodowane na twardo. Jeśli zdarzy ci się, że z jakiegoś powodu musisz obsługiwać takie stare wersje, zobacz odpowiedź autorstwa Gaks .

 80
Author: Malcolm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:17:54

Oto rozwiązanie dla dowolnej wersji SDK wykorzystującej tylko zasoby.

Res / wartości / style.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: twarde wartości kodowane są używane dla 2.2-. Więc problemy mogą wystąpić z niektórych rzadkich starych niestandardowych firmware.

 16
Author: A-IV,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-06 04:58:55

Dla 2.3+ (z dokumentacji Androida):

Użyj stylu android:TextAppearance.StatusBar.EventContent.Title dla tekstu głównego.

Użyj stylu android:TextAppearance.StatusBar.EventContent dla tekstu wtórnego.

Dla 2.2 -, zrób to, co Gaks zasugerował w innej odpowiedzi na ten wątek.

Jeśli chcesz skompilować z 2.2 i wspierać 2.3+ i obsługiwać wszystkie różne urządzenia, rozwiązanie Gaksa jest jedynym, które znam.

BTW, to co Google zasugerowało o używaniu wartości ?android:attr/textColorPrimary dla 2.2 -, nie działa. Spróbuj użyć emulatora. Sposób gaksa to jedyny sposób.

Więcej zasobów: To i to nie działają.

 13
Author: AlikElzin-kilaka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:17:54

Należy używać kolorów określonych w android.R.color

Na przykład: android.R.color.primary_text_light

Programiści ROM i projektanci skórek Androida powinni je zaktualizować, aby kolory aplikacji mogły być zgodne z resztą systemu. Obejmuje to upewnienie się, że tekst jest prawidłowo wyświetlany w całym systemie.

 2
Author: Austyn Mahoney,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-02 02:40:27

Znalazłem bardzo proste rozwiązanie bezpośrednio zmieniając nazwę atrybutu dostarczonego przez Androida.

Jak widać w tym tutorialu: http://www.framentos.com/android-tutorial/2012/02/20/how-to-create-a-custom-notification-on-android/

Wystarczy użyć innego atrybutu:

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

Mam nadzieję, że to może Ci pomóc!

 2
Author: Mauri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-21 18:49:59

Patrz na tą instrukcję: http://developer.android.com/guide/topics/ui/notifiers/notifications.html#CustomExpandedView Jeśli skonfigurujesz kolor tła dla kontenera LinearLayout, możesz mieć swoje kolory w powiadomieniu dla tekstu i tła.

Jeśli domyślny kolor tekstu powiadomienia jest zdefiniowany przez aplikację launcher, nie można go pobrać z domyślnych ustawień Androida, chyba że launcher sharing to informacje.

Jednak, czy starałeś się usunąć tę linię android:textColor = "# 000 " z układu, aby mógł automatycznie uzyskać domyślny kolor?

 1
Author: Lumis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-06 05:34:04

Używam tego na omawianym TextView:

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

Daje mi biały tekst, jeśli tło jest Czarne i czarny tekst, jeśli tło jest białe. I działa co najmniej tak daleko wstecz, jak API 19.

 1
Author: Gavin Wright,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-25 10:17:17

Rozwiązanie od @ Malckom nie pomogło mi w Lolipopie z ciemnym tłem powiadomień z powodu TextAppearance.Materiał.Powiadomienie.Tytuł to kolor zakodowany na twardo. Rozwiązanie z @ grzak zrobił, ale z pewnymi zmianami w procesie tworzenia powiadomień:

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
Author: Yurii Solopov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-05 13:01:20

Wiem, że to stare pytanie, ale może pomóc komuś innemu. ; ) Robię to w mojej aplikacji i to działa idealnie w kilku linijkach:

    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
Author: Samet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-01 22:38:32