参考資料
https://proandroiddev.com/daynight-applying-dark-mode-without-recreating-your-app-c8a62d51092d
マニフェストファイルの手動切り替えするアクティビティ層に
android:configChanges="uiMode"
を加え、そのアクティビティ内で
を定義し、そこでテーマの切り替えを行うことにより、再起動なしで実現できるようです。
以下例
マニフェスト
<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"> ///////// これを加える
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
アクティビティ
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
val nightModeFlags = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
if (nightModeFlags == Configuration.UI_MODE_NIGHT_NO){
// ライトテーマに変更する処理を記述
}else{
// ダークテーマに変更する処理を記述
}
}
しかしこれのみを行うと、切り替えを行ったアクティビティのみテーマが切り替わりません(他アクティビティは切り替わる)。なので、切り替えを行ったアクティビティのみ、テーマ変更ではなく色の差し変えを行えば、擬似的にテーマ変更が行えます。例えば、以下のようにcolorリソースにライトテーマ用の色とダークテーマ用の色をどちらも同じリソースファイルに定義しておけば、色の差し替えが可能になります。onConfigurationChanged内で、アクティビティ内のviewやら何やらに個々に色差し替える処理を行います。
<color name="colorPrimary">#fff</color>
<color name="colorPrimaryDark">#fff</color>
<color name="colorAccent">#D81B60</color>
<color name="colorText">#1A1A1A</color>
//ナイトモードの色も用意する
<color name="colorPrimaryNight">#000</color>
<color name="colorPrimaryDarkNight">#000</color>
<color name="colorTextNight">#dcdcdc</color>
参考資料
https://proandroiddev.com/daynight-applying-dark-mode-without-recreating-your-app-c8a62d51092d