为什么 Android 将我的一些可绘制对象反转为深色主题(夜间)而不是其他?
Why is Android inverting some of my drawables for dark theme (night) but not others?
我的应用使用 Theme.AppCompat.DayNight.NoActionBar
AppTheme
,并且有一个导航抽屉。我所有的可绘制对象都是 XML 矢量,其中的路径是黑色的。对于我的 sidenav 菜单中的这些可绘制对象的使用,Android 中的某处或 SDK 已反转可绘制对象,因此我的路径实际上是白色(或接近白色的颜色,也许它实际上是 colorAccent
).这个不错。
但是当我自己将同一个可绘制对象作为菜单项放置在操作栏中时,它并没有反转,仍然使用黑色路径。怎么会?我怎样才能在那里发生同样的魔法?
主题:
<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
<item name="colorAccent">@color/primaryTextColor</item>
<item name="android:navigationBarColor">#00000000</item>
</style>
主要 activity 布局中的操作栏:
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
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>
以下是我如何扩充菜单并处理片段中书签的切换(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)
}
}
倒置的 Sidenav 图标(好):
操作栏图标,没有倒置(不好):
我 99% 确定 AppCompat 的工具栏或至少 MaterialToolbar 会自动使用主题属性着色,但它看起来不像。
回答您的问题“为什么 Android 将我的一些可绘制对象反转为深色主题(夜间)而不是其他?”,这是因为使用可绘制对象的组件不着色使用主题属性。
您可以通过多种方式实现您的目标。这些都假定您希望它是 colorControlNormal
,否则请选择您喜欢的任何颜色属性。
colorControlNormal
在 AppCompat 中有默认值(深灰色),在 values-night
变体中是白色的(你可以使用 DayNight 主题)。
在矢量可绘制对象中设置图标色调
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF00FF"
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" />
</vector>
如果在您正在使用它的其他地方给这个可绘制对象着色(取决于其他地方是否应用了它自己的色调),这可能会产生不良影响。
在菜单中设置图标色调
<?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:iconTint="?attr/colorControlNormal"
app:showAsAction="always"
tools:ignore="AlwaysShowAction" />
</menu>
如果已设置,这将覆盖可绘制对象中的色调。
我的应用使用 Theme.AppCompat.DayNight.NoActionBar
AppTheme
,并且有一个导航抽屉。我所有的可绘制对象都是 XML 矢量,其中的路径是黑色的。对于我的 sidenav 菜单中的这些可绘制对象的使用,Android 中的某处或 SDK 已反转可绘制对象,因此我的路径实际上是白色(或接近白色的颜色,也许它实际上是 colorAccent
).这个不错。
但是当我自己将同一个可绘制对象作为菜单项放置在操作栏中时,它并没有反转,仍然使用黑色路径。怎么会?我怎样才能在那里发生同样的魔法?
主题:
<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
<item name="colorAccent">@color/primaryTextColor</item>
<item name="android:navigationBarColor">#00000000</item>
</style>
主要 activity 布局中的操作栏:
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
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>
以下是我如何扩充菜单并处理片段中书签的切换(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)
}
}
倒置的 Sidenav 图标(好):
操作栏图标,没有倒置(不好):
我 99% 确定 AppCompat 的工具栏或至少 MaterialToolbar 会自动使用主题属性着色,但它看起来不像。
回答您的问题“为什么 Android 将我的一些可绘制对象反转为深色主题(夜间)而不是其他?”,这是因为使用可绘制对象的组件不着色使用主题属性。
您可以通过多种方式实现您的目标。这些都假定您希望它是 colorControlNormal
,否则请选择您喜欢的任何颜色属性。
colorControlNormal
在 AppCompat 中有默认值(深灰色),在 values-night
变体中是白色的(你可以使用 DayNight 主题)。
在矢量可绘制对象中设置图标色调
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF00FF"
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" />
</vector>
如果在您正在使用它的其他地方给这个可绘制对象着色(取决于其他地方是否应用了它自己的色调),这可能会产生不良影响。
在菜单中设置图标色调
<?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:iconTint="?attr/colorControlNormal"
app:showAsAction="always"
tools:ignore="AlwaysShowAction" />
</menu>
如果已设置,这将覆盖可绘制对象中的色调。