You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android自定义通知布局切换系统主题时文字颜色不更新求助

自定义通知布局主题切换后文字颜色不更新的解决方案

问题背景

应用安装后首次启动,浅色/深色主题下自定义通知布局显示正常;但切换系统主题后,通知标题和正文的文字颜色无法自动适配,仅重新安装应用或重置手机后才能恢复,系统默认通知布局无此问题。测试设备为Redmi Note 3Pro(基于AOSP V9的自定义ROM)。

涉及代码

折叠模式布局(notification_collapse.xml)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layoutDirection="rtl"
    android:layout_width="match_parent"
    android:layout_height="64dp">

    <TextView
        android:id="@+id/TVNotTitle"
        style="@style/TextAppearance.Compat.Notification.Title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:text="عنوان پیام" />

    <ImageView
        android:id="@+id/IVNotif"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_alignParentEnd="true"
        tools:src="@drawable/sibil" />

    <TextView
        android:id="@+id/TVNotInfo"
        style="@style/TextAppearance.Compat.Notification.Info"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/TVNotTitle"
        android:layout_toStartOf="@id/IVNotif"
        android:ellipsize="end"
        android:maxLines="1"
        tools:text="این یک پیام جدید است ..." />
</RelativeLayout>

展开模式布局(notification_expand.xml)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layoutDirection="rtl"
    android:layout_margin="10dp"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:maxHeight="256dp">

    <TextView
        android:id="@+id/TVNotTitle"
        style="@style/TextAppearance.Compat.Notification.Title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:text="عنوان پیام" />

    <ImageView
        android:id="@+id/IVNotif"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:layout_alignParentEnd="true"
        tools:src="@drawable/sibil" />

    <TextView
        android:id="@+id/TVNotInfo"
        style="@style/TextAppearance.Compat.Notification.Info"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/TVNotTitle"
        android:layout_toStartOf="@id/IVNotif"
        android:ellipsize="end"
        android:maxLines="6"
        tools:text="این یک پیام جدید است ..." />
</RelativeLayout>

通知构建代码

val notification = NotificationCompat.Builder(context, myStructure.channel_id)
    .setSmallIcon(R.drawable.ic_notification)
    .setCustomContentView(collapsView)
    .setCustomBigContentView(expandView)
    .setStyle(NotificationCompat.DecoratedCustomViewStyle())
    .setContentIntent(pendingIntent)

notificationManager.notify(1, notification.build())

解决方案

1. 自定义主题适配的通知文本样式

放弃直接使用@style/TextAppearance.Compat.Notification系列样式,手动定义适配浅色/深色主题的文本样式,确保颜色引用系统主题属性:

res/values/styles.xml

<style name="NotificationTitle">
    <item name="android:textColor">?android:attr/textColorPrimary</item>
    <item name="android:textSize">16sp</item>
    <item name="android:textStyle">bold</item>
</style>

<style name="NotificationInfo">
    <item name="android:textColor">?android:attr/textColorSecondary</item>
    <item name="android:textSize">14sp</item>
</style>

res/values-night/styles.xml

<style name="NotificationTitle">
    <item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
    <item name="android:textSize">16sp</item>
    <item name="android:textStyle">bold</item>
</style>

<style name="NotificationInfo">
    <item name="android:textColor">?android:attr/textColorSecondaryInverse</item>
    <item name="android:textSize">14sp</item>
</style>

然后替换布局文件中的样式引用:

<TextView
    android:id="@+id/TVNotTitle"
    style="@style/NotificationTitle"
    ... />

<TextView
    android:id="@+id/TVNotInfo"
    style="@style/NotificationInfo"
    ... />

2. 确保视图构建使用主题上下文

构建RemoteViews时,使用ContextThemeWrapper关联当前系统主题,避免应用上下文的主题缓存影响:

val themedContext = ContextThemeWrapper(context, android.R.style.Theme_DeviceDefault)
val collapsView = RemoteViews(themedContext.packageName, R.layout.notification_collapse)
val expandView = RemoteViews(themedContext.packageName, R.layout.notification_expand)

3. 监听主题变化并刷新通知

注册系统配置变化广播,当主题切换时重新发送通知,强制更新视图样式:

class MyApp : Application() {
    private lateinit var configReceiver: BroadcastReceiver

    override fun onCreate() {
        super.onCreate()
        configReceiver = object : BroadcastReceiver() {
            override fun onReceive(context: Context?, intent: Intent?) {
                if (intent?.action == Intent.ACTION_CONFIGURATION_CHANGED) {
                    context?.let { refreshNotification(it) }
                }
            }
        }
        registerReceiver(configReceiver, IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED))
    }

    override fun onTerminate() {
        super.onTerminate()
        unregisterReceiver(configReceiver)
    }

    private fun refreshNotification(context: Context) {
        val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        val collapsView = RemoteViews(context.packageName, R.layout.notification_collapse)
        val expandView = RemoteViews(context.packageName, R.layout.notification_expand)
        
        // 重新设置通知内容(如标题、正文)
        collapsView.setTextViewText(R.id.TVNotTitle, "最新标题")
        collapsView.setTextViewText(R.id.TVNotInfo, "最新正文")
        expandView.setTextViewText(R.id.TVNotTitle, "最新标题")
        expandView.setTextViewText(R.id.TVNotInfo, "最新正文")

        val notification = NotificationCompat.Builder(context, myStructure.channel_id)
            .setSmallIcon(R.drawable.ic_notification)
            .setCustomContentView(collapsView)
            .setCustomBigContentView(expandView)
            .setStyle(NotificationCompat.DecoratedCustomViewStyle())
            .setContentIntent(pendingIntent)
            .build()
        
        notificationManager.notify(1, notification)
    }
}

4. ROM兼容性适配(针对自定义AOSP ROM)

由于设备是基于AOSP V9的自定义ROM,可能存在系统通知主题适配bug,可尝试:

  • 确保通知通道的重要性设置为IMPORTANCE_DEFAULT或更高,避免系统强制覆盖样式
  • 若需要,在通知构建时添加setColorized(true)并设置适配主题的颜色,但此操作会改变通知栏背景,按需使用

内容的提问来源于stack exchange,提问作者NimaAzhd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 01:35:26