为什么 ?android:textColorPrimary 在不同的 API 版本中得到不同的值?

Why does ?android:textColorPrimary get different values with different API versions?

我有一个白色背景的应用程序小部件。一些显示的文本使用 ?android:textColorPrimary,一些使用 ?android:textColorSecondary,一些使用我定义的颜色。

虽然出于某种原因,当我 运行 我的应用程序在牛轧糖之前(24 或更低)时,颜色是白色的,因此文本在白色背景上是不可见的,但是任何 24 或更高版本都显示为黑色或灰色。我定义的颜色总是可以的。

同样有趣的是,应用程序小部件中的代码与实际应用程序(均显示项目列表)几乎相同,并且应用程序版本(即使在这些较旧的 API 上)使用深色颜色,但出于某种原因小部件选择了白色作为文本。

如果我跟踪样式中的 XML 代码,我会得到:

    <!-- The most prominent text color.  -->
    <attr name="textColorPrimary" format="reference|color" />

这是什么意思?它如何知道最突出的文本颜色是什么?为什么它在小部件和应用程序中有所不同,为什么只在较旧的 API 版本上有所不同?

我能做些什么来解决这个问题以使其保持一致吗?我正在使用相同的主题。为什么会这样?

注:就设置特定颜色而言,这不是我要问的。当然,我可以将文本设置为黑色或其他颜色,但我想使用这些样式,以便将来可以根据需要更改颜色,尤其是因为我使用的是 day/night 主题。也许与此有关?好的,我尝试了一个普通的主题,但问题仍然存在(文本在小部件上不可见 - 只有小部件 - 在早于 API 24 时)。

如果有任何不清楚的地方,请告诉我,我会更新问题。谢谢。

嗯,?android:textColorPrimary?android:textColorSecondary是属性,是系统解析的。它们在不同平台上有所不同是可以的,因为您参考了 Android 属性。

如果您想自己定义它们,您需要创建自己的主题并将值放在那里。

What does this (textColorPrimary) mean?

这意味着,将应用当前主题的 android:textColorPrimary 中指定的值。因此,如果您在 xml 中声明了一个 TextView 并对其应用了 android:textColor="?android:textColorPrimary" ,那么该属性将从当前上下文的主题中获取,该布局正在使用该主题进行扩充。

How does it know what the most prominent text colour is?

它从您应用到 activity 的主题或从扩展视图的上下文中获取该值(参见 ContextThemeWrapperandroid:theme)。它可能因平台版本而异。根据您使用的主题,它可能会有所不同,see themes.xml

您可以在主题中覆盖该属性:

<style name="AppTheme" parent="...">
    ...
    <item name="android:textColorPrimary">@color/someColor</item>
</style>

现在,您已成功覆盖 android:textColorPrimary 属性,因此此后任何使用此主题上下文扩充的视图在引用 ?android:textColorPrimary 时都会看到此覆盖值。

Why is it different in the widget vs the app, and why only on older API versions?

您的小部件可能已使用特定主题进行了扩充,而应用具有不同的主题。如果他们有相同的主题 - 这些属性将是相同的。