自定义通知布局和文字颜色
我的应用程序显示一些通知,并根据用户的喜好,它可能会使用通知中的自定义布局。 它运作良好,但有一个小问题 – 文字颜色 。 股票Android和几乎所有的制造商皮肤使用黑色文本对通知文本的浅色背景,但三星不:他们的通知下拉有一个黑暗的背景,默认通知布局中的文本是白色的。
所以这会导致一个问题:不使用任何花哨布局的通知显示正常,但是使用自定义布局的通知很难阅读,因为文本是黑色的,而不是默认的白色。 即使官方文档只是为TextView
设置#000
颜色,所以我找不到任何指针。
一个用户很友善地截取了这个问题的截图:
那么如何在我的布局中使用设备的默认通知文字颜色 ? 我宁愿不动手改变基于手机型号的文本颜色,因为这需要大量的更新,而使用自定义ROM的人可能仍然会遇到问题,这取决于他们使用的皮肤。
Malcolm的解决scheme在API> = 9的情况下工作良好。 以下是旧API的解决scheme:
诀窍是创build标准通知对象,然后遍历由Notification.setLatestEventInfo(...)
创build的默认contentView
。 当您find正确的TextView时,只需获取tv.getTextColors().getDefaultColor()
。
以下是提取默认文本颜色和文本大小的代码(按比例缩放密度像素 – 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; } }
调用extractColors
即。 在你的服务的onCreate()。 然后,当您创build自定义通知时,您需要的颜色和文本大小位于notification_text_color
和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);
解决scheme是使用内置的样式。 您需要的样式在Android 2.3和Android 4.x中称为TextAppearance.StatusBar.EventContent
。 在Android 5.x素材通知中,使用其他几种样式: TextAppearance.Material.Notification
, TextAppearance.Material.Notification.Title
和TextAppearance.Material.Notification.Line2
。 只需为文本视图设置适当的文本外观,您将获得必要的颜色。
如果你对我是如何到达这个解决scheme感兴趣的话,这里是我的痕迹。 代码摘录取自Android 2.3。
-
当您使用
Notification
并通过使用内置手段设置文本时,下面的行创build布局:RemoteViews contentView = new RemoteViews(context.getPackageName(), com.android.internal.R.layout.status_bar_latest_event_content);
-
提到的布局包含以下
View
,它负责查看通知文本:<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" />
-
所以结论是所需的样式是
TextAppearance.StatusBar.EventContent
,其定义如下所示:<style name="TextAppearance.StatusBar.EventContent"> <item name="android:textColor">#ff6b6b6b</item> </style>
你应该在这里注意到这个样式实际上并没有引用任何内置的颜色,所以最安全的方法是应用这种样式而不是内置的颜色。
还有一件事:在Android 2.3(API Level 9)之前,既没有样式也没有颜色,只有硬编码的值。 如果由于某种原因您碰巧需要支持这些旧版本,请参阅Gaks的答案 。
这里是仅使用资源的任何SDK版本的解决scheme。
RES /值/ 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 /值-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 /布局/ 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:硬编码值用于2.2-。 因此,一些罕见的旧定制固件可能会出现问题。
对于2.3+(来自Android文档 ):
主要文本使用样式android:TextAppearance.StatusBar.EventContent.Title
。
为辅助文本使用样式android:TextAppearance.StatusBar.EventContent
。
对于2.2-,按照Gaks在另一个回答这个主题的build议做什么。
如果你想编译2.2并支持2.3+,并且支持所有各种设备,Gaks的解决scheme是我所知道的唯一的解决scheme。
顺便说一句,谷歌build议使用的价值?android:attr/textColorPrimary
为2.2,不起作用。 只需使用模拟器来尝试。 Gaks的方式是唯一的方法。
更多的资源: 这和这是行不通的。
你应该使用android.R.color
指定的颜色
例如: android.R.color.primary_text_light
自定义ROM开发人员和Android皮肤devise师应该更新这些,以便您的应用程序的颜色可以与系统的其他部分保持一致。 这包括确保您的文本在整个系统中正确显示。
我发现了一个非常简单的解决scheme,直接更改Android提供的属性的名称。
正如您在本教程中所看到的: http : //www.framentos.com/android-tutorial/2012/02/20/how-to-create-a-custom-notification-on-android/
你只需要使用不同的属性:
<item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
希望这可以帮到你!
看看这个指示: http : //developer.android.com/guide/topics/ui/notifiers/notifications.html#CustomExpandedView如果你设置你的LinearLayout容器的背景颜色,那么你可以有你的颜色通知文本和的背景。
如果通知文本的默认颜色是由启动程序应用程序定义的,那么您将无法从android默认设置中检索它,除非启动程序正在分割这些信息。
但是,你有尝试从你的布局中删除这行android:textColor =“#000”,以便它可以自动获得默认的颜色?
由于TextAppearance.Material.Notification.Title是系统硬编码颜色,来自@Malckom的解决scheme没有帮助我在黑暗的通知背景的Lolipop。 来自@grzaks的解决scheme做了,但在通知创build过程中进行了一些更改:
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(); } } // ...
我知道这是一个古老的问题,但它可以帮助别人; )我在我的应用程序中这样做,并在几行完美的作品:
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; }