Moja aplikacja wyświetla niektóre powiadomienia iw zależności od preferencji użytkownika może używać w powiadomieniu niestandardowego układu. Działa dobrze, ale jest mały problem - kolory tekstu . Standardowe skórki Androida i prawie wszystkie skórki producentów używają czarnego tekstu na jasnym tle do tekstu powiadomienia, ale Samsung nie: ich menu rozwijane powiadomień ma ciemne tło, a tekst w domyślnym układzie powiadomień jest biały.
To powoduje problem: powiadomienia, które nie używają żadnych fantazyjnych układów, wyświetlają się dobrze, ale ten, który używa niestandardowego układu, jest trudny do odczytania, ponieważ tekst jest czarny zamiast domyślnego białego. Nawet oficjalna dokumentacja ustawia tylko #000
kolor a TextView
, więc nie mogłem znaleźć tam żadnych wskazówek.
Użytkownik był na tyle uprzejmy, że wykonał zrzut ekranu problemu:
Jak więc w moich układach używać domyślnego koloru tekstu powiadomienia z urządzenia ? Wolałbym nie zaczynać dynamicznie zmieniać koloru tekstu w oparciu o model telefonu, ponieważ wymaga to wielu aktualizacji, a osoby z niestandardowymi pamięciami ROM mogą nadal mieć problem, w zależności od używanej skóry.
Odpowiedzi:
Rozwiązanie autorstwa Malcolma działa dobrze z API> = 9. Oto rozwiązanie dla starszego interfejsu API:
Sztuczka polega na utworzeniu standardowego obiektu powiadomienia, a następnie przejściu do domyślnego
contentView
utworzonego przezNotification.setLatestEventInfo(...)
. Gdy znajdziesz odpowiedni TextView, po prostu pobierz pliktv.getTextColors().getDefaultColor()
.Oto kod, który wyodrębnia domyślny kolor tekstu i rozmiar tekstu (w pikselach o skalowanej 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; } }
Zadzwoń
extractColors
tj. w onCreate () Twojej usługi. Następnie podczas tworzenia powiadomienia niestandardowego należy określić żądany kolor i rozmiar tekstunotification_text_color
oraznotification_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);
źródło
Solution by Malcolm works fine with API>=9
. Wiesz, Android i producenci to trudna sprawa. Użyj tego rozwiązania na każdej platformie.Rozwiązaniem jest użycie wbudowanych stylów. Styl, którego potrzebujesz, jest nazywany
TextAppearance.StatusBar.EventContent
w Androidzie 2.3 i Androidzie 4.x. W Androidzie 5.x materialne powiadomienia użyć kilku innych stylów:TextAppearance.Material.Notification
,TextAppearance.Material.Notification.Title
, iTextAppearance.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 systemu Android 2.3.
Podczas używania
Notification
i ustawiania tekstu przy użyciu środków wbudowanych następujący wiersz tworzy układ:RemoteViews contentView = new RemoteViews(context.getPackageName(), com.android.internal.R.layout.status_bar_latest_event_content);
Wspomniany układ zawiera następujące elementy,
View
które są odpowiedzialne za przeglądanie 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" />
Wniosek jest taki, że potrzebny jest styl
TextAppearance.StatusBar.EventContent
, którego definicja wygląda następująco:<style name="TextAppearance.StatusBar.EventContent"> <item name="android:textColor">#ff6b6b6b</item> </style>
Należy zauważyć, że ten styl w rzeczywistości nie odnosi się do żadnego z wbudowanych kolorów, więc najbezpieczniejszym sposobem jest zastosowanie tego stylu zamiast niektórych wbudowanych kolorów.
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 stałe. Jeśli z jakiegoś powodu musisz obsługiwać takie stare wersje, zobacz odpowiedź Gaks .
źródło
style="@android:style/TextAppearance.StatusBar.EventContent"
) i uzyskujesz odpowiedni kolor dla tekstu. Będzie to miało miejsce#ff6b6b6b
w przypadku waniliowego Androida lub innego koloru ustawionego przez dostawcę urządzenia.Oto rozwiązanie dla dowolnej wersji SDK korzystającej tylko z zasobów.
<?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>
<?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>
... <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" /> ...
PS: wartości zakodowane na stałe są używane dla 2.2-. Dlatego mogą wystąpić problemy z niektórymi rzadkimi, starymi niestandardowymi oprogramowaniem układowym.
źródło
Wersja 2.3+ (z dokumentacji systemu Android ):
Użyj stylu
android:TextAppearance.StatusBar.EventContent.Title
dla tekstu podstawowego.Użyj stylu
android:TextAppearance.StatusBar.EventContent
dla tekstu dodatkowego.W przypadku wersji 2.2- zrób to, co zasugerował Gaks w innej odpowiedzi na ten wątek.
Jeśli chcesz kompilować z wersją 2.2 i obsługiwać 2.3+ i obsługiwać wszystkie różne urządzenia, rozwiązanie Gaks jest jedynym, jakie znam.
BTW, to, co sugerował Google przy używaniu wartości
?android:attr/textColorPrimary
dla 2.2-, nie działa. Po prostu spróbuj za pomocą emulatora. Droga Gaksa jest jedyną drogą.Więcej zasobów: to i to nie działa.
źródło
Używam tego w omawianym TextView:
style="@style/TextAppearance.Compat.Notification.Title"
Daje mi biały tekst, jeśli tło jest czarne, a czarny tekst, jeśli tło jest białe. I działa przynajmniej od API 19.
źródło
Powinieneś używać kolorów określonych w
android.R.color
Na przykład:
android.R.color.primary_text_light
Niestandardowi programiści ROM i projektanci skór dla Androida powinni je aktualizować, aby kolory Twojej aplikacji były zgodne z resztą systemu. Obejmuje to zapewnienie prawidłowego wyświetlania tekstu w całym systemie.
źródło
android.R.color
? Wszystkie kolory tekstu mają zarówno „ciemne”, jak i „jasne” odmiany.Spójrz na te instrukcje: http://developer.android.com/guide/topics/ui/notifiers/notifications.html#CustomExpandedView Jeśli ustawisz kolor tła dla kontenera LinearLayout, możesz mieć kolory w powiadomieniach o tekście i tło.
Jeśli domyślny kolor tekstu powiadomienia jest zdefiniowany przez aplikację uruchamiającą, nie można go pobrać z domyślnych ustawień Androida, chyba że program uruchamiający udostępnia te informacje.
Czy jednak próbowałeś usunąć ten wiersz android: textColor = "# 000" ze swojego układu, aby mógł automatycznie uzyskać domyślny kolor?
źródło
Znalazłem bardzo proste rozwiązanie bezpośrednio zmieniające nazwę atrybutu dostarczanego przez Androida.
Jak widać w tym samouczku: http://www.framentos.com/android-tutorial/2012/02/20/how-to-create-a-custom-notification-on-android/
Musisz tylko użyć innego atrybutu:
<item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
Mam nadzieję, że to ci pomoże!
źródło
Wiem, że to stare pytanie, ale mogłoby pomóc komuś innemu; ) Robię to w mojej aplikacji i działa to idealnie w kilku wierszach:
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; }
źródło
Rozwiązanie od @Malckom nie pomogło mi w Lolipopie z ciemnym tłem powiadomień z powodu TextAppearance.Material.Notification.Title to systemowy kolor zakodowany na stałe. Rozwiązanie od @grzaks tak, 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(); } } // ...
źródło
Oto, co pomogło mi rozwiązać ten błąd. Dodaj następujące elementy do styles.xml
<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>
źródło
W układzie rozwijanym lub zwiniętym ustawionym
android:background
jako,"@android:color/transparent"
ponieważ automatycznie przyjmuje kolor motywu powiadomienia urządzenia i ustawia go jako tło<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" />
Kolor widoku tekstu definiuje czerń i biel, jak w
Resource/color
pliku w prostym pliku kolorów, a także w pliku kolorów w trybie nocnymźródło