Можно ли сделать ночной классификатор для заставки на Android?

Фон

Я знаю, что в Android Q есть новая функция, наконец, поддерживающая темную тему (написал здесь о обнаружение его).

Я также знаю, что есть функция «Ночной свет» (здесь), из-за чего экран становится более желтым.

Поддержка выбора темы вручную — это то, что я делал годами (используя просто setTheme в первой строке кода Activity onCreate), но я хочу знать, есть ли что-то автоматическое, что позволит мне установить его еще до того, как приложение действительно запустится, на экране-заставке.

Эта проблема

Кажется, очень старая функция (начиная с API 8!) существует на Android очень давно, имея в ресурсах квалификатор «ночь», и я даже не пробовал ее.

К сожалению, потому что о «темной теме» и ночных вещах теперь чаще говорят как о новых функциях ( здесь, например), я не могу найти, о чем старый.

Однако, глядя на некоторые статьи и документацию, кажется, что это почти полностью вручную:

Что я пробовал

Я попытался установить различные темы соответственно:

res/drawable/splash.xml

  <layer-list xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:opacity="opaque" tools:ignore="UnusedAttribute">
    <item android:gravity="fill">
      <shape android:shape="rectangle">
        <solid android:color="#fff"/>
      </shape>
    </item>
    ...
  </layer-list>

res/drawable-v29/splash.xml

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:opacity="opaque" tools:ignore="UnusedAttribute">
  <item android:gravity="fill">
    <shape android:shape="rectangle">
      <solid android:color="?attr/colorSurface"/>
    </shape>
  </item>
  ...
</layer-list>

res/drawable-night/splash.xml

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:opacity="opaque" tools:ignore="UnusedAttribute">
  <item android:gravity="fill">
    <shape android:shape="rectangle">
      <solid android:color="#000"/>
    </shape>
  </item>
  ...
</layer-list>

манифест

res/values/themes.xml

  <style name="AppTheme_splash" parent="@style/Theme.MaterialComponents.DayNight">
    <item name="android:windowBackground">@drawable/splash</item>
  </style>

res/values-v26/themes.xml

  <style name="AppTheme_splash" parent="@style/Theme.MaterialComponents.DayNight">
    <item name="android:windowSplashscreenContent">@drawable/splash</item>
  </style>

Я попытался удалить android:windowBackground и android:windowSplashscreenContent, пытаясь проверить, автоматически ли это, но это не помогло.

Вопросы

В основном я просто хочу знать о ночном режиме и могу ли я использовать его для заставки:

  1. Когда включится «ночной режим», который Android так долго поддерживает?

  2. Это os-global режим? Пользователь контролирует?

  3. Это автоматически? Или полностью вручную текущим приложением?

  4. Остается ли режим позже, даже если я установил его вручную с помощью приложения, и приложение было убито?

  5. Можно ли установить тему приложения (имеется в виду заставка), чтобы использовать это, чтобы при включенном ночном режиме оно использовало его для темного фона?

  6. Подходит ли мой код для этого?


person android developer    schedule 29.06.2019    source источник
comment
Да, эта функция поддерживается, но вам нужно использовать новый appCompat API, чтобы ваши стили работали правильно. Чтобы установить определенный режим, вам нужно устанавливать его при запуске каждый раз, поэтому, если пользователь изменит тему, вы должны сохранить настройки и восстановить это при запуске. Я предлагаю вам установить режим в Application.OnCreate() и помнить, что этот режим не сохраняется, вам нужно сохранить предпочтение самостоятельно.   -  person Mihai    schedule 29.06.2019
comment
Я забыл упомянуть, что вы можете установить его и для отдельных действий. И он использует старые квалификаторы ночных ресурсов, они просто подправили реализацию в новом AppCompat, чтобы упростить использование. Также ваша тема заставки будет соответствовать этому режиму. так как вы установили его во время запуска приложения.   -  person Mihai    schedule 29.06.2019
comment
@Mihai Не могли бы вы показать рабочий образец того, как он работает на заставке? Насколько я знаю, я не могу использовать какой-либо код до того, как он будет показан, не так ли? Кроме того, как я уже писал, речь не идет об активности. Для Activity уже есть несколько решений. И почему вы думаете, что это связано с appCompat? Он был доступен с Android API 8... Пожалуйста, объясните. Что такое ночной режим? Не путайте с темной темой Android Q, как я уже писал...   -  person android developer    schedule 30.06.2019
comment
Android Q использует старые квалификаторы ночных ресурсов. И в новом AppCompat они изменили реализацию, чтобы она была более согласованной на разных уровнях API и более простой в использовании разработчиками (у нее была неудобная реализация, потому что она была создана для использования Android Auto). Таким образом, старые квалификаторы ночного ресурса используются для обеспечения этого нового ночного режима.   -  person Mihai    schedule 30.06.2019
comment
Подробнее об этом можно прочитать здесь developer.android.com/preview/features/darktheme. и ночной режим используется темной темой Android Q, и он работает до 8, потому что те квалификаторы ресурсов, которые там были, они просто использовались для предоставления ресурсов, когда приложение использовалось в пристыкованной машине, у них были некоторые обратные вызовы, запускающие его для вашего приложение. Но они изменили это поведение в новом appCompat, так что теперь вы можете легко указать системе, какие ресурсы использовать. И если вы вызовете Application.onCreate(), это также повлияет на ваш экран-заставку.   -  person Mihai    schedule 30.06.2019
comment
Не могли бы вы показать это? Я пробовал несколько раз, и это ничего не дало. Пожалуйста, объясните больше и ответьте на вопросы в ответе, а не в комментариях.   -  person android developer    schedule 30.06.2019
comment
У меня также есть настройка уровня приложения для ночного режима и дневного режима с помощью AppCompat. Каждая часть моего приложения, включая фактический LaunchActivity, правильно соответствует настройке, но НЕ заставке, установленной через ‹item name=android:windowBackground›@drawable/launch_image‹/item›. Я не могу заставить это изображение делать что-либо, кроме как использовать изображение в дневном режиме.   -  person StainlessSteelRat    schedule 31.03.2020
comment
@StainlessSteelRat Обновлено с ответом. Забыл про этот вопрос :)   -  person android developer    schedule 31.03.2020


Ответы (1)


На самом деле можно иметь ночной модификатор для заставки.

К сожалению, это происходит сразу, до того, как можно будет использовать какой-либо код. Так что это полностью зависит от настроек ОС, а не самого приложения.

Кроме того, в среде IDE есть досадная проблема, заключающаяся в том, что для каждого действия сначала используется эта тема, которую я создал для заставки.

Если не считать этих двух недостатков, работает нормально, и вы сами можете убедиться в этом в моем приложении здесь.

Здесь:

res/drawable/splash.xml

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
    android:opacity="opaque" tools:ignore="UnusedAttribute">
    <item android:gravity="fill">
        <shape android:shape="rectangle">
            <solid android:color="#fff" />
        </shape>
    </item>
    <item
        android:width="48dp" android:height="48dp" android:gravity="center">
        <bitmap
            android:gravity="center" android:src="@mipmap/ic_launcher_foreground" />
    </item>
</layer-list>

res/drawable-night/splash.xml

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
    android:opacity="opaque" tools:ignore="UnusedAttribute">
    <item android:gravity="fill">
        <shape android:shape="rectangle">
            <solid android:color="#000" />
        </shape>
    </item>
    <item
        android:width="48dp" android:height="48dp" android:gravity="center">
        <bitmap
            android:gravity="center" android:src="@mipmap/ic_launcher_foreground" />
    </item>
</layer-list>

themes.xml

    <style name="AppTheme_splash" parent="@style/Theme.MaterialComponents.DayNight">
        <item name="android:windowBackground">@drawable/splash</item>
        <item name="android:navigationBarColor" tools:targetApi="lollipop">@android:color/transparent</item>
        <item name="android:statusBarColor" tools:targetApi="lollipop">?android:colorBackground</item>
        <item name="colorSecondary">?colorAccent</item>
        <item name="android:colorSecondary" tools:targetApi="n_mr1">?colorAccent</item>
    </style>

манифест

  <application android:theme="@style/AppTheme_splash" ...">
person android developer    schedule 31.03.2020
comment
Спасибо! вечером попробую на своей! - person StainlessSteelRat; 01.04.2020