Custom notification layouts and text colors

My application displays some notifications, and depending on user settings, it may use a custom layout in the notification. It works well, but there is a small problem - the color of the text . Android Android and almost all the manufacturerโ€™s skins use black text on a light background for notification text, but Samsung does not: their drop-down menu has a dark background, and the text in the default notification layout is white.

So this causes a problem: notifications that don't use any fancy layouts look good, but one that uses a custom layout is hard to read because the text is black, not white by default. Even the official documentation just sets the color #000 to TextView , so I could not find any pointers there.

The user was kind enough to take a screenshot:

Screenshothot

So how do I use the default text color of notifications from a device in my layouts? I would prefer not to start dynamically changing the color of the text based on the phone model, as this requires a lot of updates, and people with custom ROMs may still get the problem, depending on the skin they use.

+77
android notifications android-notifications
Feb 01 '11 at 19:57
source share
11 answers

Malcolm's solution works fine with API> = 9. Here's a solution for an older API:

The trick is to create a standard notification object, and then move the default contentView created using Notification.setLatestEventInfo(...) . When you find the correct TextView, just get tv.getTextColors().getDefaultColor() .

Here is the code that retrieves the text color and default text size (in pixels of the pixel density - 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 i.e. in onCreate () of your service. Then, when you create a custom notification, the required color and text size are in notification_text_color and 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); 
+58
Sep 06 2018-11-11T00:
source share

The solution is to use inline styles. The desired style is called TextAppearance.StatusBar.EventContent in Android 2.3 and Android 4.x. Material notifications for Android 5.x use several other styles: TextAppearance.Material.Notification , TextAppearance.Material.Notification.Title and TextAppearance.Material.Notification.Line2 . Just set the appropriate text for the text view and you will get the necessary colors.

If you are interested in how I came to this decision, here is my trace of crackers. Excerpts from the code are taken from Android 2.3.

  • When you use Notification and set the text using the built-in tools, the following line creates a layout:

     RemoteViews contentView = new RemoteViews(context.getPackageName(), com.android.internal.R.layout.status_bar_latest_event_content); 
  • The specified layout contains the following View , which is responsible for viewing the notification text:

     <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" /> 
  • So, the conclusion is that the desired TextAppearance.StatusBar.EventContent style, the definition of which is as follows:

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

    Here you should note that this style does not actually refer to any of the built-in colors, so the safest way is to apply this style instead of the built-in color.

One more thing: before Android 2.3 (API level 9) there were no styles or colors, there were only hard-coded values. If for some reason you have to support such old versions, see the Answer from Gaks .

+80
Feb 08 2018-11-11T00:
source share

Here is a solution for any version of the SDK using only resources.

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

PS: Hard coded values โ€‹โ€‹are used for 2.2-. Thus, problems can arise when using some rare old firmware.

+16
Jan 06 2018-12-12T00:
source share

For 2.3+ (From Documentation for Android ):

Use android:TextAppearance.StatusBar.EventContent.Title style android:TextAppearance.StatusBar.EventContent.Title for body text.

Use the android:TextAppearance.StatusBar.EventContent style android:TextAppearance.StatusBar.EventContent for secondary text.

For 2.2- do what Gax suggested in another answer to this thread.

If you want to compile with 2.2 and support 2.3+ and support all the different devices, the Gaks solution is the only thing I know.

By the way, Google suggested using the value ?android:attr/textColorPrimary for 2.2- does not work. Just try using an emulator. Gax's method is the only way.

Additional resources: This and this do not work.

+13
Dec 06 2018-11-21T00:
source share

You must use the colors specified in android.R.color

For example: android.R.color.primary_text_light

Custom drive developers and Android skin developers must update them, so your application colors may match the rest of the system. This includes ensuring that text is displayed correctly throughout the system.

+2
Feb 02 '11 at 2:40
source share

Take a look at the following instructions: http://developer.android.com/guide/topics/ui/notifiers/notifications.html#CustomExpandedView If you set your background color for the LinearLayout container, you can get your colors in the notification for text and background.

If the default color for the notification text is determined by the launch application, you cannot get it from the default settings for Android, unless the launcher exchanges this information.

However, will you try to remove this android: textColor = "# 000" line from your layout so that it can automatically get the default color?

+1
Feb 06 2018-11-11T00:
source share

I found a very simple solution that directly changes the attribute name provided by Android.

As you can see in this lesson: http://www.framentos.com/android-tutorial/2012/02/20/how-to-create-a-custom-notification-on-android/

You need to use only another attribute:

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

Hope this helps you!

+1
Feb 21 '12 at 18:49
source share

I use this on TextView in the question:

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

This gives me white text if the background is black and black text if the background is white. And this works, at least before API 19.

+1
Aug 25 '18 at 10:17
source share

The solution from @Malckom did not help me in Lolipop with a dark notification background due to TextAppearance.Material.Notification.Title - the system hard code. A solution from @grzaks happened, but with some changes in the process of creating notifications:

 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
Mar 05 '16 at 12:51 on
source share

I know this is an old question, but it can help someone else; ) I do this in my application and works fine on several lines:

  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
Jan 01 '16 at 22:38
source share

Here is what helped me solve this error. Add the following to 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> 
0
May 13 '19 at 18:48
source share



All Articles