ContextCompat.getColor()忽略NightMode

Mat*_*ito 5 android android-appcompat android-dark-theme

TL,DR;

ContextCompat.getColor()values-night/colors.xml启用夜间模式时应使用夜间颜色(),但不使用。

这是问题所在:

嗨,大家好,

因此,我正在为我的Android应用程序实现深色主题,我称其为启用它: AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);

我在中设置了颜色,values/colors.xml并在中设置了深色版本values-night/colors.xml。颜色的变化取决于nightMode,但:

当我使用时ContextCompat.getColor(getApplicationContext(), R.id.myColor),它将使用常规颜色(values/colors.xml)而不是夜间颜色(values-night/colors.xml)。

在我中build.gradle,我设置了以下这些:

implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.core:core-ktx:1.2.0-beta01'
Run Code Online (Sandbox Code Playgroud)

有人可以告诉我我做错了什么吗?

PS:我已经看过以下问题,它不能回答此问题/sf/ask/4044576301/

W0r*_*0le 22

我在夜间模式下遇到了类似的问题。有些屏幕很好,但其他屏幕保持常规主题。最后,我发现我正在使用应用程序的上下文而不是当前的活动上下文来实例化一些视图。出于某种原因,应用程序的上下文不会跟踪此类信息。

因此,更新您的代码以使用 current 的活动上下文而不是应用程序上下文。

供其他用户参考。避免:

ContextCompat.getColor(getApplicationContext(), R.id.myColor)
Run Code Online (Sandbox Code Playgroud)

并使用:

// In a Activity
ContextCompat.getColor(this, R.id.myColor)

// In a View
ContextCompat.getColor(getContext(), R.id.myColor)

// In a Fragment (check against null because getContext can trigger a NPE
Context context = getContext()
if (context != null) {
    ContextCompat.getColor(context, R.id.myColor)
}
Run Code Online (Sandbox Code Playgroud)

  • `Application` 是“原始”上下文,它将始终引用默认样式的值并忽略任何配置。另一方面,“AppCompatActivity”确实处理正确的配置并链接到“AppCompatDelegate”。 (4认同)

Bah*_*man 6

应用程序上下文对当前主题或白天/夜晚一无所知,因此如果您从应用程序上下文获取资源,您将在默认应用程序主题中获取资源。此问题的解决方案是使用活动/片段上下文,但在某些情况下,您可能没有活动或片段,而只有应用程序上下文。我创建了一个上下文包装类来将日夜主题添加到应用程序上下文中:

import android.content.Context
import android.content.res.Configuration
import android.content.res.Resources
import androidx.annotation.ColorRes
import androidx.annotation.DrawableRes
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.content.ContextCompat

class ThemedContext(application: Context) {

    private val themedContext: Context

    init {
        val res: Resources = application.resources
        val configuration = Configuration(res.configuration)
        val filter = res.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK.inv()

        configuration.uiMode = when (AppCompatDelegate.getDefaultNightMode()) {
            AppCompatDelegate.MODE_NIGHT_NO -> Configuration.UI_MODE_NIGHT_NO or filter
            AppCompatDelegate.MODE_NIGHT_YES -> Configuration.UI_MODE_NIGHT_YES or filter
            else -> res.configuration.uiMode
        }

        themedContext = application.createConfigurationContext(configuration)
    }

    fun getColor(@ColorRes id: Int) = ContextCompat.getColor(themedContext, id)
    fun getDrawable(@DrawableRes id: Int) = ContextCompat.getDrawable(themedContext, id)
    //todo Add other getter methods as needed...
}
Run Code Online (Sandbox Code Playgroud)

这段代码已经过测试并且可以工作。