Android 自定义通知布局和文本颜色

Android 自定义通知布局和文本颜色,android,notifications,android-notifications,Android,Notifications,Android Notifications,我的应用程序显示了一些通知,根据用户偏好,它可能会在通知中使用自定义布局。它工作正常,但有一个小问题--文本颜色。股票安卓和几乎所有制造商的皮肤使用黑色文本对光背景的通知文本,但三星没有:他们的通知下拉菜单有一个黑暗的背景和默认通知布局中的文本是白色的 因此,这就产生了一个问题:不使用任何奇特布局的通知显示良好,但使用自定义布局的通知很难阅读,因为文本是黑色而不是默认的白色。甚至连浏览器都只是为文本视图设置了#000颜色,所以我在那里找不到任何指针 一位用户很友好地拍摄了问题的屏幕截图: 因此

我的应用程序显示了一些通知,根据用户偏好,它可能会在通知中使用自定义布局。它工作正常,但有一个小问题--文本颜色。股票安卓和几乎所有制造商的皮肤使用黑色文本对光背景的通知文本,但三星没有:他们的通知下拉菜单有一个黑暗的背景和默认通知布局中的文本是白色的

因此,这就产生了一个问题:不使用任何奇特布局的通知显示良好,但使用自定义布局的通知很难阅读,因为文本是黑色而不是默认的白色。甚至连浏览器都只是为
文本视图设置了
#000
颜色,所以我在那里找不到任何指针

一位用户很友好地拍摄了问题的屏幕截图:


因此,如何在布局中使用设备的默认通知文本颜色?我不希望开始根据手机型号动态改变文本颜色,因为这需要大量更新,而使用自定义ROM的用户可能仍然会遇到问题,具体取决于他们使用的皮肤。

您应该使用android.R.color
中指定的颜色

例如:
android.R.color.primary\u text\u light


定制ROM开发者和Android皮肤设计师应该更新这些,这样你的应用程序的颜色可以与系统的其他部分保持一致。这包括确保文本在整个系统中正确显示。

查看以下说明: 如果为LinearLayout容器设置背景色,则可以在文本和背景的通知中使用颜色

如果通知文本的默认颜色由launcher应用程序定义,则您无法从android默认设置中检索它,除非launcher正在共享此信息


但是,您是否尝试从布局中删除这一行android:textColor=“#000”,以便自动获得默认颜色?

解决方案是使用内置样式。在Android 2.3和Android 4.x中,您需要的样式称为
TextAppearance.StatusBar.EventContent
。在Android 5.x中,材质通知使用了几种其他样式:
TextAppearance.material.Notification
TextAppearance.material.Notification.Title
,以及
TextAppearance.material.Notification.Line2
。只需为文本视图设置适当的文本外观,即可获得必要的颜色

如果您对我是如何得出这个解决方案感兴趣,下面是我的面包屑线索。代码摘录摘自Android2.3

  • 使用
    通知
    并使用内置方式设置文本时,以下行将创建布局:

    RemoteViews contentView = new RemoteViews(context.getPackageName(),
            com.android.internal.R.layout.status_bar_latest_event_content);
    
  • 上述布局包含以下
    视图
    ,负责查看通知文本:

    <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"
        />
    
    这里您应该注意到,此样式实际上并不引用任何内置颜色,因此最安全的方法是应用此样式而不是某些内置颜色


  • 还有一件事:在Android 2.3(API级别9)之前,既没有样式,也没有颜色,只有硬编码的值。如果出于某种原因您不得不支持这些旧版本,请参阅Malcolm的。

    解决方案,该解决方案在API>=9的情况下运行良好。以下是针对旧API的解决方案:

    技巧是创建标准通知对象,然后遍历由
    notification.setLateStevenInfo(…)
    创建的默认
    contentView
    。找到正确的文本视图后,只需获取
    tv.getTextColor().getDefaultColor()

    下面是提取默认文本颜色和文本大小(以缩放密度像素-sp为单位)的代码

    对于2.3+(从):

    对主文本使用样式
    android:TextAppearance.StatusBar.EventContent.Title

    使用样式
    android:TextAppearance.StatusBar.EventContent
    作为辅助文本

    对于2.2-,请执行此线程的另一个答案中的操作

    如果您想针对2.2进行编译并支持2.3+,并且支持所有种类的设备,那么我只知道Gaks的解决方案

    顺便说一句,谷歌建议在2.2-版本中使用值
    ?android:attr/textColorPrimary
    ,这是行不通的。只需使用模拟器进行尝试。Gaks的路是唯一的路


    更多资源:并且不起作用。

    这里提供了仅使用资源的任何SDK版本的解决方案

    res/values/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>
    
    
    ?android:attr/textColorPrimaryInverse
    大胆的
    ?android:attr/textColorPrimaryInverse
    
    res/values-v9/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>
    
    
    
    res/layout/my_notification.xml

    。。。
    ...
    

    注:硬编码值用于2.2-。因此,一些罕见的老式定制固件可能会出现问题。

    我发现了一个非常简单的解决方案,可以直接更改Android提供的属性名称

    正如您在本教程中所看到的:

    您只需要使用不同的属性:

    <item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
    
    android:attr/textColorPrimaryInverse
    希望这能帮助你

    来自@Malckom的解决方案在Lolipop上没有帮助,因为TextAppearance.Material.notification.Title是系统硬编码的颜色。 @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();
        }
    }
    // ...
    

    我知道这是一个老问题,但它可以帮助其他人;) 我在我的应用程序中做到了这一点,在以下几行代码中效果完美:

        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;
    
        }
    

    我在所讨论的文本视图中使用此选项:

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

    如果背景是黑色,它会给我白色文本,如果背景是白色,它会给我黑色文本。它的工作原理至少可以追溯到API 19

    以下是我解决此错误的方法。将以下内容添加到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>
    
    
    #FF6B
    
    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;
    
        }
    
    style="@style/TextAppearance.Compat.Notification.Title"
    
        <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>
    
    <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" />