返回

Android 本地通知:图标与按钮颜色定制指南

java

Android 本地通知图标与按钮颜色定制

在 Android 应用中,本地通知是用户接收信息的重要渠道。 恰当的颜色配置可以增强通知的视觉效果和可读性。 这篇文章讨论如何处理通知图标和操作按钮的颜色,以适应不同 Android 版本。

图标颜色处理

在 Android 9 及更低版本中,可以通过setColor方法简单设置通知图标颜色,如下代码展示了该方式。

builder.setColor(ContextCompat.getColor(this, R.color.color_secondary));

然而,Android 12 引入了自适应图标特性。 应用的通知图标,若非单色资源,将自动变灰并添加颜色背景。为了有效利用系统特性,应该提供一个单色(仅白色)的通知图标。 setColor会应用于这个单色图标的背景颜色。

一种处理方法是在drawable目录下为不同设备密度(dpi)创建单色矢量图或png图像。 可以将原彩色图标转换成只保留形状和透明度(白色前景,透明背景)的版本。对于vector drawables ,你可以使用一个类似于 android:fillColor="#FFFFFF"的定义确保白色前景色。

确保 drawable资源设置为只含前景色的白色图形,并且透明背景。 对于已有的图标,可以考虑使用图像处理工具或转换服务将它们转换成适当的单色形式。对于矢量图形资源(VectorDrawable),保证 android:fillColor 为纯白色 (#FFFFFF) 或利用着色属性进行统一处理。

示例的通知构建器代码展示如下:

 NotificationCompat.Builder builder = new NotificationCompat.Builder(this, channelId)
          .setSmallIcon(R.drawable.ic_notification)
           .setColor(ContextCompat.getColor(this, R.color.color_secondary))

这个示例代码会设置R.drawable.ic_notification作为通知的图标,并应用R.color.color_secondary作为通知的背景色。 需要强调的是, ic_notification 需要是一个单色白色图标,背景为透明的图形。

操作按钮颜色

Android 操作按钮的颜色控制变得更加细致,特别是在不同版本之间。 在Android 12上,为了给操作按钮设置颜色,需要使用 Spannable 对文字进行装饰。 例如下方的代码,它使用ForegroundColorSpan为指定文字设置颜色。

protected static Spannable getActionText(Context context, String text, int colorRes) {
    Spannable spannable = new SpannableString(text);
    spannable.setSpan(
        new ForegroundColorSpan(ContextCompat.getColor(context, colorRes)), 0, spannable.length(), 0);
    return spannable;
}

应用该方法添加动作的代码如下:

builder.addAction(R.drawable.ic_stat_push, getActionText(context, buttonName, R.color.color_secondary), launchIntent);

Android 14 的更新改变了行为,导致 ForegroundColorSpan 无法生效。要保持一致的按钮样式,使用主题化属性可以作为较好的选择。可以在 styles.xml 文件中,通过设置android:textColorcolorSecondary 或其它所需颜色值来间接控制。 例如:

    <style name="Notification.ActionButton" parent="TextAppearance.Material.Button">
        <item name="android:textColor">?attr/colorSecondary</item>
    </style>

然后在 addAction 中应用该样式:


 NotificationCompat.Builder builder = new NotificationCompat.Builder(this, channelId);
          //....省略其他构建器设置
 builder.addAction(new NotificationCompat.Action.Builder(
               R.drawable.ic_stat_push,
               buttonName, launchIntent)
          .setSemanticAction(NotificationCompat.Action.SEMANTIC_ACTION_NONE) //确保颜色可以被设置
          .setShowsUserInterface(false) //避免应用默认界面样式干扰
          .setStyle(new NotificationCompat.Action.WearableExtender().setContentIntent(launchIntent)) //使样式在 Wear 设备上有效
          .build())
        ;

          

这里,代码先获取了已设置好的action主题样式资源。 之后构建Action 时,为它指定一个语义行为 NotificationCompat.Action.SEMANTIC_ACTION_NONE,保证后续样式定义能生效。 为了兼容性和统一的用户体验,代码还利用了NotificationCompat.Action.WearableExtender().setContentIntent(launchIntent) 对不同的通知通道进行样式统一。 setShowsUserInterface(false) 的作用在于避免使用系统默认的用户界面样式,让自定义样式能够正确应用。
务必确保你的按钮文字使用自定义主题中定义的文字颜色,以保证其在各Android版本和设备上正确显示。

这些处理方式结合起来,能够为用户提供在多个Android版本上都有良好体验的本地通知。 对各种版本的兼容需要耐心和反复测试,才能保证在各设备上达到期望的显示效果。