为什么 Android 会为黑暗主题(夜间)反转我的一些可绘制对象而不是其他对象?

Eli*_*iot 5 android android-dark-theme

我的应用程序使用Theme.AppCompat.DayNight.NoActionBar AppTheme, 并有一个导航抽屉。我所有的 drawable 都是 XML 向量,其中的路径是黑色的。为了使用我的 sidenav 菜单中的这些 drawable,Android 或 SDK 中的某个地方已经反转了 drawable,这样我的路径实际上是白色的(或者接近白色的颜色,也许实际上是colorAccent)。这很好。

但是当我将相同的可绘制对象作为菜单项放置在操作栏中时,它并没有反转并且仍然使用黑色路径。怎么来的?我如何在那里发生同样的魔法?

主题:

<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
    <item name="colorAccent">@color/primaryTextColor</item>
    <item name="android:navigationBarColor">#00000000</item>
</style>
Run Code Online (Sandbox Code Playgroud)

主活动布局中的操作栏:

<androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
Run Code Online (Sandbox Code Playgroud)

menu/action_bar.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <item android:id="@+id/bookmarkAction"
        android:title="@string/bookmark"
        android:icon="@drawable/ic_bookmark_off"
        app:showAsAction="always"
        tools:ignore="AlwaysShowAction" />
</menu>
Run Code Online (Sandbox Code Playgroud)

下面是我如何扩充菜单并处理从片段中切换书签的方法(这ToggleButton似乎不会为我节省任何工作):

override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
    inflater.inflate(R.menu.action_bar, menu)
    super.onCreateOptionsMenu(menu, inflater)
}

// Swap out the bookmark icon in the options menu depending
// on whether this command is bookmarked or not.
override fun onPrepareOptionsMenu(menu: Menu) {
    super.onPrepareOptionsMenu(menu)

    val bookmarkMenuItem = menu.getItem(0)
    val commandName = viewModel.command.value?.name

    if (model?.bookmarkedCommands?.contains(commandName)!!) {
        Log.v(logTag, "${commandName} is bookmarked")

        bookmarkMenuItem?.icon = ContextCompat.getDrawable(requireContext(),
            R.drawable.ic_bookmark_on)
    }
    else {
        Log.v(logTag, "${commandName} is not bookmarked")

        bookmarkMenuItem?.icon = ContextCompat.getDrawable(requireContext(),
            R.drawable.ic_bookmark_off)
    }
}
Run Code Online (Sandbox Code Playgroud)

Sidenav 图标,倒置(好):

侧导航

操作栏图标,未倒置(坏):

在此处输入图片说明

ata*_*ulm 5

我 99% 确信 AppCompat\xe2\x80\x99s Toolbar 或至少 MaterialToolbar 会自动使用主题属性着色,但它看起来不像。

\n

要回答您的问题“为什么 Android 将我的一些可绘制对象反转为黑暗主题(夜间)而不是其他?”,这是因为使用可绘制对象的组件不使用主题属性进行着色。

\n
\n

有几种方法可以实现您想要的目标。这些都假设您希望它是colorControlNormal,否则选择您喜欢的任何颜色属性。

\n

colorControlNormal在 AppCompat 中具有默认值(深灰色),并且在values-night变体中为白色(您可以通过使用 DayNight 主题获得)。

\n

在矢量绘图中设置图标色调

\n
<vector xmlns:android="http://schemas.android.com/apk/res/android"\n    android:width="24dp"\n    android:height="24dp"\n    android:tint="?attr/colorControlNormal"\n    android:viewportWidth="24"\n    android:viewportHeight="24">\n    <path\n        android:fillColor="#FF00FF"\n        android:pathData="M17,3H7c-1.1,0 -1.99,0.9 -1.99,2L5,21l7,-3 7,3V5c0,-1.1 -0.9,-2 -2,-2z" />\n</vector>\n
Run Code Online (Sandbox Code Playgroud)\n

这可能会产生潜在的不良影响,即在您使用该可绘制对象的其他地方着色(取决于其他地方是否应用其自己的色调)。

\n

在菜单中设置图标色调

\n
<?xml version="1.0" encoding="utf-8"?>\n<menu xmlns:android="http://schemas.android.com/apk/res/android"\n    xmlns:app="http://schemas.android.com/apk/res-auto"\n    xmlns:tools="http://schemas.android.com/tools">\n\n    <item android:id="@+id/bookmarkAction"\n        android:title="@string/bookmark"\n        android:icon="@drawable/ic_bookmark_off"\n        app:iconTint="?attr/colorControlNormal"\n        app:showAsAction="always"\n        tools:ignore="AlwaysShowAction" />\n</menu>\n
Run Code Online (Sandbox Code Playgroud)\n

如果设置了这一设置,它将覆盖可绘制对象中的色调。

\n