DayNight: utilice el modo oscuro sin volver a crear la aplicación | autor: Jamshid Mamatkulov | Octubre de 2020

Debes agregar primero configChanges modo de actividad en su archivo de manifiesto

<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:configChanges="uiMode"> //add this line

<intent-filter>
<action android:name="android.intent.action.MAIN" />

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

Esta línea de código evita que su aplicación se vuelva a crear cuando el modo oscuro se usa manualmente o desde la barra de notificaciones, por lo que si usó colors-night.xml, se omitirá porque su aplicación no se volverá a crear. Así que todos los colores en la mano ahora.

En mi caso, creé colores con «noche» terminando en mis colores originales en colors.xml

<color name="colorPrimary">#fff</color>
<color name="colorPrimaryDark">#fff</color>
<color name="colorAccent">#D81B60</color>
<color name="colorText">#1A1A1A</color>

//night mode
<color name="colorPrimaryNight">#000</color>
<color name="colorPrimaryDarkNight">#000</color>
<color name="colorTextNight">#dcdcdc</color>

Después de cambiar los colores, vaya a la página Actividad y sobrescriba onConfigurationChanged y use colores según la condición nightModeFlags

override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
val nightModeFlags = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASKif (nightModeFlags == Configuration.UI_MODE_NIGHT_NO){
applyDayNight(OnDayNightStateChanged.DAY)
}else{
applyDayNight(OnDayNightStateChanged.NIGHT)
}
}
private fun applyDayNight(state: Int){
if (state == OnDayNightStateChanged.DAY){
//apply day colors for your views
}else{
//apply night colors for your views
}
}

onConfygurationChanged el método será llamado cada vez que cambie el estado de DayNight, por ejemplo, habilite o deshabilite el modo oscuro desde la barra de notificaciones o utilícelo manualmente desde el código.

Fácil, solo crea una interfaz y amplía todos los fragmentos en los que quieras usar el modo nocturno.

interface OnDayNightStateChanged {

fun onDayNightApplied(state: Int)

companion object{
const val DAY = 1
const val NIGHT = 2
}
}

Y amplíe su fragmento con esta interfaz

class YourFragment: Fragment(), OnDayNightStateChanged {

override fun onDayNightApplied(state: Int) {
if(state == OnDayNightStateChanged.DAY){
//apply day colors for your views
}else{
//apply night colors for your views
}
}
}

Y tienes que informar a tus fragmentos de que eso es todo. Tu actividad es responsable de reportar fragmentos. Cada vez que cambia la configuración, sus fragmentos también obtienen un estado de Día Nocturno.

private fun applyDayNight(state: Int){
if (state == OnDayNightStateChanged.DAY){
//apply day colors for your views
}else{
//apply night colors for your views
}
supportFragmentManager.fragments.forEach {
if(it is OnDayNightStateChanged){
it.onDayNightApplied(state)
}
}
}

La barra de estado y la barra de navegación también deben estar oscuras con texto e íconos en blanco, y viceversa.

Si es una rutina diaria, agregue esto a su applyDayNight en su actividad

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (nightModeFlags == Configuration.UI_MODE_NIGHT_NO) {
decorView.systemUiVisibility = decorView.systemUiVisibility or View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
}
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
var flags: Int = decorView.systemUiVisibility
flags = flags or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR

if (nightModeFlags == Configuration.UI_MODE_NIGHT_NO) {
decorView.systemUiVisibility = flags
}
window.statusBarColor = yourColorDay
}else
window.statusBarColor = yourColorNight

AppCompatDelegate
.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) // night mode
AppCompatDelegate
.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) // day mode
//this will follow system settings (from notification bar)
AppCompatDelegate
.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
El resultado final

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *