Как принудительно применить темную тему в Android Studio?

Согласно документам, мне нужны только установить 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?


person Richard    schedule 02.02.2020    source источник


Ответы (2)


Не так работает темный режим на Android 10. .

Во-первых, Android не добавляет к вашей теме каким-либо волшебным образом .Dark, независимо от того, активировал ли пользователь темный режим или нет. У вас есть android:theme="@style/AppTheme". Таким образом, Android будет использовать AppTheme все время, а ваш AppTheme.Dark не будет использоваться.

Во-вторых, идея DayNight заключается в том, что вы все время используете его в качестве базовой темы, а Android будет переключаться между нормальным и темным режимами в зависимости от запроса пользователя. Итак, если вы переключите AppTheme на расширение DayNight и избавитесь от AppTheme.Dark, вы будете соответствовать тому, что требуется документация.

android:forceDarkAllowed предназначен для случаев, когда вы не можете использовать тему DayNight и хотите, чтобы Android попытался автоматически преобразовать ваш пользовательский интерфейс в темную тему. Если вы хотите сохранить AppTheme расширение Light вместо DayNight, это может сработать (я лично не пробовал это с темой MaterialComponents). Но даже в этом случае это будет только тогда, когда пользователь включил темный режим (например, нажал на плитку тени уведомления).

Например, в этом примере приложения я использую 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>

У меня разные определения этих цветов в _ 17_ и _ 18_. Я не использую forceDarkAllowed. И когда пользователь переключает ночной режим, мой пользовательский интерфейс меняется с:

DayNight normal

to:

Темный режим DayNight

Как сделать так, чтобы при запуске приложения MainActivity автоматически настраивался на использование AppTheme.Dark (т.е. темный режим) с помощью android: forceDarkAllowed?

Вы этого не сделаете.

Если вам все время нужна темная тема, используйте обычную тему (не Light, не DayNight).

person CommonsWare    schedule 02.02.2020
comment
Спасибо! Мне нравится ваше очень подробное объяснение. Я знал, что могу перейти на темную тему программно и по запросу пользователя. Однако я действительно запутался в этом разделе android:forceDarkAllowed. Я попробую перечитать его еще раз, чтобы увидеть, не пропустил ли я что-нибудь. Спасибо, правда. Это потрясающе. - person Richard; 02.02.2020
comment
@Richard: android:forceDarkAllowed в основном предназначен для существующих приложений, которые хотят попытаться взломать поддержку темного режима без изменения своих тем и пользовательского интерфейса. Он работает на удивление хорошо, но все равно допускает ошибки. Вам нужно будет тщательно протестировать свое приложение, чтобы убедиться, что автоматическое преобразование не делает некоторые вещи некрасивыми или непригодными для использования. - person CommonsWare; 02.02.2020
comment
Ах я вижу. Я тестировал android:forceDarkAllowed стиль Theme.AppCompat и Theme.MaterialComponents, и он работал, как вы сказали. Он волшебным образом преобразует цвет в режим темной темы. Затем я попробовал еще раз на Theme.AppCompat.DayNight/Light и Theme.MaterialComponents.Light/DayNight, и это не сработало. - person Richard; 03.02.2020
comment
Я прочитал эту строку First, Android does not magically append .Dark to your theme at any point и сразу пришел к выводу, что это ответ от CommonsWare. - person Bugs Happen; 21.05.2021

  1. Если ваше приложение использует темную тему (например, Theme.Material), Force Dark НЕ применяется. Точно так же, если тема вашего приложения унаследована от темы DayNight, Force Dark НЕ будет применяться из-за автоматического переключения тем.
  2. Темная тема доступна в Android 10 (уровень API 29) и выше. Убедитесь, что уровень API вашего устройства 29 +, что ваш целевой SDK в gradle равен 29.
  3. There are two ways to apply dark theme:
    1. DayNight - custom-able theme - you control how dark/light theme will look like
    2. Force dark - вы управляете светлой темой, и если пользователь выбирает темный режим, система преобразует ваши представления в темную тему во время выполнения.
person Hadas    schedule 02.02.2020