Код: Выделить всё
Theme.MaterialComponents.DayNight.NoActionBarЦель
- При первом запуске: приложение должно соответствовать теме ОС (необязательно).
- После того, как пользователь вручную выбирает Светлый или Темный, приложение должно всегда использовать эту сохраненную тему, в том числе при возврате из внешних приложений (браузера) через deeplink.
При запуске активности я применяю тему перед super.onCreate():
Код: Выделить всё
override fun onCreate(savedInstanceState: Bundle?) {
initTheme()
super.onCreate(savedInstanceState)
setContentView(...)
}
private fun initTheme() {
when (Configs.getCurrentTheme(this)) {
"light" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
"dark" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
}
}
Код: Выделить всё
object Configs {
private const val selectedTheme = "selectedTheme"
fun saveSelectedTheme(context: Context, value: String) {
PreferencesManager.getInstance(context).save(selectedTheme, value)
}
fun getCurrentTheme(context: Context) =
PreferencesManager.getInstance(context).read(selectedTheme).let {
it.ifEmpty {
when (context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) {
Configuration.UI_MODE_NIGHT_YES -> "dark"
else -> "light"
}
}
}
}
Код: Выделить всё
Configs.saveSelectedTheme(
this,
if (Configs.getCurrentTheme(this) == "light") "dark" else "light"
)
finish()
startActivity(Intent(this, MainActivity::class.java))
На Android 14 и более ранних версиях все в порядке.
На Android 15 и 16 (проверено на Samsung / Honor / NothingPhone):
- Тема ОС Темная
- Сохраненная в приложении тема Светлая ()
Код: Выделить всё
MODE_NIGHT_NO - В приложении я открываю браузер (URL)
Код: Выделить всё
ACTION_VIEW - Я возвращаюсь в приложение через deeplink
- Существующие/старые фрагменты (созданные до браузера) по-прежнему отображаются Светлым
- Все новые фрагменты, созданные после возврата, становятся темными (системная тема)
- Результатом является пользовательский интерфейс со смешанной темой во всех фрагментах.
Ограничения/дополнительные детали
- У меня нет android:configChanges для uiMode и т. д.
- Родительская тема — Theme.MaterialComponents.DayNight.NoActionBar
- Предотвращает смешанные темы на Android 15/16 при возврате из браузера или глубокой ссылки
- Предпочтительно не полагается на recreate()
- Вызов AppCompatDelegate.setDefaultNightMode(...) ранее (до super.onCreate)
- Повторное применение дня/ночи в onResume() / onNewIntent() через Deleate.applyDayNight()
- Использование Deleate.localNightMode
- Перезапуск активности при несоответствии (иногда работает, но не всегда; также попытка воссоздания вызывает сбои в моем стеке навигации)
Каков правильный и надежный способ (особенно на Android 15/16), чтобы приложение оставалось в сохраненном режиме «День/ночь» после возврата из внешнего приложения (браузера) через deeplink, не получая при этом смешанные тематические фрагменты?
Если известно изменение поведения Android 15/16 или рекомендуемый обходной путь (например, использование обработки uiMode, переноса контекста, конфигурации манифеста или специальной Использование AppCompat API), поделитесь.
Подробнее здесь: https://stackoverflow.com/questions/798 ... t-theme-in
Мобильная версия