【问题标题】:How do I force apply a dark theme on Android?如何在 Android 上强制应用深色主题?
【发布时间】:2020-02-02 14:02:56
【问题描述】:

根据docs,我只需要在我的活动清单中设置android:forceDarkAllowed=true,并从parent="Theme.MaterialComponents.DayNight"继承主题。我试过了,但是没有用。

这是我的清单文件:

<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>

这是我的styles.xml 样式:

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

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

我尝试使用以下代码获取活动的主题名称:

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

它显示com.example.name:style/AppTheme 而不是AppTheme.Dark。我怎样才能使它在我运行应用程序时,MainActivity 自动设置为使用AppTheme.Dark(即暗模式)使用android:forceDarkAllowed

【问题讨论】:

    标签: android android-theme android-dark-theme


    【解决方案1】:

    这不是dark mode 在 Android 10 上的工作方式。

    首先,无论用户是否启用暗模式,Android 都不会在任何时候神奇地将.Dark 附加到您的主题。你有android:theme="@style/AppTheme"。所以,Android 会一直使用AppTheme,而你的AppTheme.Dark 不会被使用。

    其次,DayNight 背后的想法是您始终将其用作基本主题,Android 将根据用户请求在正常模式和暗模式之间切换。因此,如果您将AppTheme 切换为扩展DayNight,并摆脱AppTheme.Dark,您将匹配the documentation 的要求。

    android:forceDarkAllowed 适用于您无法使用DayNight 主题并且希望Android 尝试自动将您的UI 转换为深色主题的情况。如果您想保持AppTheme 扩展Light 而不是DayNight,这可能有效(我个人没有尝试过MaterialComponents 主题)。但是,即便如此,它也只会在用户启用暗模式时(例如,点击通知阴影图块)。

    例如,在this sample app 中,我使用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>
    

    我在res/values/res/values-night/ 中对这些颜色有不同的定义。我不使用forceDarkAllowed。而且,当用户切换夜间模式时,我的 UI 来自:

    到:

    我怎样才能做到这一点,以便在我运行应用程序时,MainActivity 使用 android:forceDarkAllowed 自动将自己设置为使用 AppTheme.Dark(即暗模式)?

    你没有。

    如果您一直想要深色主题,请使用常规主题(不是Light,而不是DayNight)。

    【讨论】:

    • 谢谢!我喜欢你非常彻底的解释。我知道我可以根据用户要求以编程方式更改为深色主题。但是,我对android:forceDarkAllowed 部分感到非常困惑。我会尝试再读一遍,看看我是否遗漏了什么。谢谢你,真的。这是完美的。
    • @Richard:android:forceDarkAllowed 主要适用于想要尝试在不修改其主题和 UI 的情况下支持暗模式支持的现有应用程序。它工作得非常好,但仍然会出错。您需要彻底测试您的应用,以确认自动转换不会使某些东西变得丑陋或无法使用。
    • 啊,我明白了。我在Theme.AppCompatTheme.MaterialComponents 样式上测试了android:forceDarkAllowed,它按照您的说法工作。它神奇地将颜色转换为深色主题模式。然后我又在Theme.AppCompat.DayNight/LightTheme.MaterialComponents.Light/DayNight 上试了一遍,还是不行。
    • 我读了这行First, Android does not magically append .Dark to your theme at any point 并立即得出结论,这个答案来自CommonsWare。
    【解决方案2】:
    1. 如果您的应用使用深色主题(例如 Theme.Material),则将应用 Force Dark。同样,如果您的应用的主题继承自 DayNight 主题,由于主题自动切换,Force Dark 将应用。
    2. 深色主题在 Android 10(API 级别 29)及更高版本中可用。确保您设备的 API 级别为 29 + 并且您在 gradle 中的目标 SDK 为 29。
    3. 有两种方法可以应用深色主题:
      1. DayNight - 可自定义主题 - 您可以控制深色/浅色主题的外观
      2. 强制变暗 - 您可以控制浅色主题,如果用户选择深色模式,系统会在运行时将您的视图转换为深色主题。

    【讨论】:

      【解决方案3】:

      无论当前系统设置如何,都有一些设置允许动态设置白天或夜晚。

      每个选项都直接映射到 AppCompat.DayNight 之一 模式:

      Light - MODE_NIGHT_NO
      Dark - MODE_NIGHT_YES
      System default - MODE_NIGHT_FOLLOW_SYSTEM
      

      要切换主题,请调用 AppCompatDelegate.setDefaultNightMode()。

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

      这适用于设置 DayNight 主题。如果您尝试利用 Android 10 中的 Force Dark,它适用于 .Light 子主题。它不会应用于任何DayNight 或固有的黑暗主题。

      应用必须通过设置来选择强制黑暗 android:forceDarkAllowed="true" 在活动的主题中。这 属性设置在所有系统和 AndroidX 提供的光 主题,例如 Theme.Material.Light。

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

      在此之下,文档还指定了如何在资源或代码中排除某些项目。

      Force Dark 可以在特定视图上使用 android:forceDarkAllowed 布局属性或带有 setForceDarkAllowed().

      除此之外,还有一些方法可以检测当前系统的亮/暗设置并使用上述选项对其进行响应,但这是另一篇文章。

      对于黑暗主题来说,这不是一个很好的解决方案,对于与已接受答案的任何重叠,我深表歉意,但我不同意声称某些事情是不可能的,因为它不是首选。

      【讨论】:

        猜你喜欢
        • 2015-10-04
        • 1970-01-01
        • 2013-05-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多