我的应用程序显示了一些通知,并且根据用户首选项,它可能会在通知中使用自定义布局。它运作良好,但有一个小问题 - 文字颜色。 Stock Android和几乎所有制造商的皮肤都使用黑色文本作为通知文本的浅色背景,但三星没有:他们的通知下拉背景为黑色,默认通知布局中的文本为白色。
因此,这会导致一个问题:不使用任何花哨布局的通知显示正常,但使用自定义布局的通知很难阅读,因为文本是黑色而不是默认白色。即使official documentation只为#000
设置TextView
颜色,我也找不到任何指针。
用户非常友好地截取问题的屏幕截图:
所以如何在布局中使用设备中的默认通知文字颜色?我宁愿不开始根据手机型号动态改变文字颜色,因为这需要大量更新,而定制ROM的人可能仍会遇到问题,具体取决于他们正在使用的皮肤。
答案 0 :(得分:80)
解决方案是使用内置样式。您需要的样式在Android 2.3和Android 4.x中称为TextAppearance.StatusBar.EventContent
。在Android 5.x素材通知中使用其他几种样式:TextAppearance.Material.Notification
,TextAppearance.Material.Notification.Title
和TextAppearance.Material.Notification.Line2
。只需为文本视图设置合适的文本外观,即可获得必要的颜色。
如果您对我的解决方案感兴趣,这是我的面包屑痕迹。代码摘录取自Android 2.3。
当您使用Notification
并使用内置方式设置文本时,以下行会创建布局:
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)之前,既没有样式,也没有颜色,只有硬编码值。如果您因某些原因而不得不支持此类旧版本,请参阅answer by Gaks。
答案 1 :(得分:58)
Malcolm的解决方案适用于API&gt; = 9。以下是旧API的解决方案:
诀窍是创建标准通知对象,然后遍历由contentView
创建的默认Notification.setLatestEventInfo(...)
。当您找到正确的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()。然后,当您创建自定义通知时,所需的颜色和文字大小位于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);
答案 2 :(得分:16)
以下是仅使用资源的任何SDK版本的解决方案。
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"
/>
...
P.S:硬编码值用于2.2-。因此,一些罕见的旧自定义固件可能会出现问题。
答案 3 :(得分:13)
对于2.3+(来自Android documentation):
使用样式android:TextAppearance.StatusBar.EventContent.Title
作为主要文字。
使用样式android:TextAppearance.StatusBar.EventContent
作为辅助文本。
对于2.2-,在这个帖子的另一个答案中做Gaks suggested。
如果您想针对2.2进行编译并支持2.3+,并支持所有各种设备,Gaks的解决方案是我所知道的唯一解决方案。
BTW,谷歌建议将值?android:attr/textColorPrimary
用于2.2-,是行不通的。只需使用模拟器进行尝试即可。 Gaks的方式是唯一的方式。
答案 4 :(得分:2)
您应该使用android.R.color
例如:android.R.color.primary_text_light
自定义ROM开发人员和Android皮肤设计人员应该更新这些,以便您的应用程序的颜色可以与系统的其余部分保持一致。这包括确保您的文本在整个系统中正确显示。
答案 5 :(得分:1)
查看此说明:http://developer.android.com/guide/topics/ui/notifiers/notifications.html#CustomExpandedView 如果您为LinearLayout容器设置背景颜色,那么您可以在通知中获取文本和背景颜色。
如果启动器应用程序定义了通知文本的默认颜色,那么除非启动器正在分析此信息,否则无法从Android默认设置中检索它。
但是,您是否尝试从布局中删除此行android:textColor =“#000”,以便它可以自动获取默认颜色?
答案 6 :(得分:1)
我找到了一个非常简单的解决方案,可以直接更改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>
希望这可以帮到你!
答案 7 :(得分:1)
我在有问题的TextView上使用它:
style="@style/TextAppearance.Compat.Notification.Title"
如果背景是黑色,它会给我白色文本,如果背景是白色,则会给我黑色文本。而且至少可以追溯到API19。
答案 8 :(得分:0)
由于TextAppearance.Material.Notification.Title是一个系统硬编码的颜色,来自@Malckom的解决方案并没有帮助我在Lolipop的黑暗通知背景。 来自@grzaks的解决方案确实如此,但在通知创建过程中有一些变化:
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();
}
}
// ...
答案 9 :(得分:0)
我知道这是一个古老的问题,但它可以帮助别人; ) 我在我的应用程序中执行此操作,并且在几行中完美无缺:
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;
}
答案 10 :(得分:0)
这是解决我错误的方法。将以下内容添加到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>
答案 11 :(得分:0)
在可扩展或折叠式布局中,将android:background
设置为"@android:color/transparent"
,因为这会自动采用设备通知主题的颜色并设置为背景
<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" />
您的textview颜色在简单颜色文件以及夜间模式颜色文件中的Resource/color
文件中定义了黑白