简体   繁体   English

如何在 Android 上强制应用深色主题?

[英]How do I force apply a dark theme on Android?

According to the docs , I only need to set android:forceDarkAllowed=true in my activity manifest and inherit theme from parent="Theme.MaterialComponents.DayNight" .根据文档,我只需要在我的活动清单中设置android:forceDarkAllowed=true并从parent="Theme.MaterialComponents.DayNight"继承主题。 I tried that, but it didn't work.我试过了,但没有用。

Here's my manifest file:这是我的清单文件:

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity
        android:name=".MainActivity"
        android:forceDarkAllowed="true">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

And here's my styles.xml styles:这是我的styles.xml styles:

<style name="AppTheme" parent="Theme.MaterialComponents.Light">
    ...
</style>

<style name="AppTheme.Dark" parent="Theme.MaterialComponents.DayNight">
    ...
</style>

I tried to get the theme name of the activity by using this code below:我尝试使用以下代码获取活动的主题名称:

resources.getResourceName(
    packageManager.getPackageInfo(packageName, PackageManager.GET_META_DATA)
        .applicationInfo.theme
)

It shows me com.example.name:style/AppTheme and not AppTheme.Dark .它向我显示com.example.name:style/AppTheme而不是AppTheme.Dark How can I make it so that when I run the application, the MainActivity automatically sets itself to use AppTheme.Dark (ie dark mode) using android:forceDarkAllowed ?我怎样才能做到这样,当我运行应用程序时, MainActivity会使用android:forceDarkAllowed自动将自己设置为使用AppTheme.Dark (即黑暗模式)?

That is not how dark mode works on Android 10.这不是暗模式在 Android 10 上的工作方式。

First, Android does not magically append .Dark to your theme at any point, regardless of whether or not the user enabled dark mode.首先,无论用户是否启用了暗模式,Android 都不会在任何时候神奇地将.Dark附加到您的主题。 You have android:theme="@style/AppTheme" .你有android:theme="@style/AppTheme" So, Android will use AppTheme all the time, and your AppTheme.Dark will not be used.所以,Android 会一直使用AppTheme ,而你的AppTheme.Dark不会被使用。

Second, the idea behind DayNight is that you use that as you base theme all the time, and Android will switch between normal and dark modes based on user request.其次, DayNight背后的想法是你一直使用它作为你的基本主题,Android 将根据用户请求在正常和黑暗模式之间切换。 So, if you switch AppTheme to extend DayNight , and get rid of AppTheme.Dark , you will be matching what the documentation calls for.因此,如果您切换AppTheme以扩展DayNight ,并摆脱AppTheme.Dark ,您将匹配文档要求的内容。

android:forceDarkAllowed is for cases where you are not in position to use a DayNight theme, and you want Android to try to automatically convert your UI to a dark theme. android:forceDarkAllowed适用于您无法使用DayNight主题的情况,并且您希望 Android 尝试自动将您的 UI 转换为深色主题。 If you wanted to keep AppTheme extending Light instead of DayNight , this might work (I personally have not tried it with a MaterialComponents theme).如果您想让AppTheme扩展Light而不是DayNight ,这可能会奏效(我个人还没有尝试过使用MaterialComponents主题)。 But, even then, it will only be when the user has enabled dark mode (eg, tapped on the notification shade tile).但是,即便如此,也只有在用户启用暗模式(例如,点击通知栏)时才会如此。

For example, inthis sample app , I use DayNight for my theme:例如,在这个示例应用程序中,我使用DayNight作为我的主题:

<resources>

  <!-- Base application theme. -->
  <style name="AppTheme" parent="Theme.AppCompat.DayNight">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
  </style>

</resources>

I have different definitions for those colors in res/values/ and res/values-night/ .我对res/values/res/values-night/这些颜色有不同的定义。 I do not use forceDarkAllowed .我不使用forceDarkAllowed And, when the user toggles night mode, my UI goes from:而且,当用户切换夜间模式时,我的用户界面从:

昼夜正常

to:到:

日夜黑暗模式

How can I make it so that when I run the application, the MainActivity automatically sets itself to use AppTheme.Dark (ie dark mode) using android:forceDarkAllowed?我怎样才能让它在我运行应用程序时,MainActivity 使用 android:forceDarkAllowed 自动设置自己使用 AppTheme.Dark(即暗模式)?

You don't.你没有。

If you want a dark theme all the time, use a regular theme (not Light , not DayNight ).如果您一直想要深色主题,请使用常规主题(不是Light ,不是DayNight )。

  1. If your app uses a dark theme (such as Theme.Material), Force Dark will NOT be applied.如果您的应用使用深色主题(例如 Theme.Material),则不会应用 Force Dark。 Similarly, if your app's theme inherits from a DayNight theme, Force Dark will NOT be applied, due to the automatic theme switching.同样,如果您的应用程序的主题继承自 DayNight 主题,则由于自动主题切换,将不会应用 Force Dark。
  2. Dark theme is available in Android 10 (API level 29) and higher.深色主题在 Android 10(API 级别 29)及更高版本中可用。 Make sure that your device's API level is 29 + that your target SDK in the gradle is 29.确保您设备的 API 级别为 29 + gradle中的目标 SDK 为 29。
  3. There are two ways to apply dark theme:有两种方法可以应用深色主题:
    1. DayNight - custom-able theme - you control how dark/light theme will look like DayNight - 可自定义的主题 - 您可以控制深色/浅色主题的外观
    2. Force dark - you control the light theme, and if the user chooses dark mode the system will convert your views to dark theme at runtime.强制暗 - 您控制亮主题,如果用户选择暗模式,系统将在运行时将您的视图转换为暗主题。

There are settings to allow dynamically setting day or night regardless of the current system setting.无论当前系统设置如何,都有一些设置允许动态设置白天或晚上。

Each of the options map directly to one of the AppCompat.DayNight modes:每个选项 map 直接到 AppCompat.DayNight 模式之一:

 Light - MODE_NIGHT_NO Dark - MODE_NIGHT_YES System default - MODE_NIGHT_FOLLOW_SYSTEM

To switch the theme, call AppCompatDelegate.setDefaultNightMode().要切换主题,请调用 AppCompatDelegate.setDefaultNightMode()。

https://developer.android.com/guide/topics/ui/look-and-feel/darktheme#change-themes https://developer.android.com/guide/topics/ui/look-and-feel/darktheme#change-themes

This would apply to setting a DayNight theme.这适用于设置 DayNight 主题。 If you are trying to take advantage of the Force Dark in Android 10, it applies to the .Light sub-themes.如果您尝试利用 Android 10 中的 Force Dark,它适用于.Light子主题。 It will not be applied to any of the DayNight or inherently dark themes.它不会应用于任何DayNight或固有的黑暗主题。

Apps must opt-in to Force Dark by setting android:forceDarkAllowed="true" in the activity's theme.应用程序必须通过在活动主题中设置 android:forceDarkAllowed="true" 来选择加入 Force Dark。 This attribute is set on all of the system and AndroidX provided light themes, such as Theme.Material.Light.该属性设置在所有系统和 AndroidX 提供的浅色主题上,例如 Theme.Material.Light。

https://developer.android.com/guide/topics/ui/look-and-feel/darktheme#force-dark https://developer.android.com/guide/topics/ui/look-and-feel/darktheme#force-dark

Below that, the documentation also specifies how to exclude certain items, either in resources or code.在此之下,文档还指定了如何在资源或代码中排除某些项目。

Force Dark can be controlled on specific views with the android:forceDarkAllowed layout attribute or with setForceDarkAllowed().可以使用 android:forceDarkAllowed 布局属性或 setForceDarkAllowed() 在特定视图上控制 Force Dark。

Beyond that, there are ways to detect the current system light / dark setting and respond to it using the options above, but that is for another post.除此之外,还有一些方法可以检测当前系统亮/暗设置并使用上面的选项对其做出响应,但那是另一篇文章的内容。

It's not a great solution for a dark theme and I apologize for any overlap with the accepted answer, but I do not agree with claiming something isn't possible because it isn't preferred.对于黑暗主题来说,这不是一个很好的解决方案,对于与已接受答案的任何重叠,我深表歉意,但我不同意声称某些事情是不可能的,因为它不是首选。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM