Skip to content

Commit 5ccb3d5

Browse files
authored
Merge pull request #13 from odaridavid/feat-change-settings-icon
theme settings icon changing on theme changes by the system
2 parents 149ad0f + 10387a2 commit 5ccb3d5

File tree

7 files changed

+115
-34
lines changed

7 files changed

+115
-34
lines changed

app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ android {
1313

1414
def versionMajor = 1
1515
def versionMinor = 1
16-
def versionPatch = 1
16+
def versionPatch = 2
1717

1818
applicationId "com.github.odaridavid.designpatterns"
1919
minSdkVersion 21

app/src/main/java/com/github/odaridavid/designpatterns/base/BaseActivity.kt

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import com.github.odaridavid.designpatterns.helpers.SdkUtils.versionFrom
1313
import com.github.odaridavid.designpatterns.helpers.SdkUtils.versionUntil
1414
import com.github.odaridavid.designpatterns.helpers.ThemeUtils
1515

16-
abstract class BaseActivity : AppCompatActivity() {
16+
abstract class BaseActivity : AppCompatActivity(), ISystemThemeChangeListener<Any> {
1717

1818
private val powerManager: PowerManager by lazy {
1919
getSystemService(Context.POWER_SERVICE) as PowerManager
@@ -39,7 +39,7 @@ abstract class BaseActivity : AppCompatActivity() {
3939
ThemeUtils.THEME_DARK -> setDarkSystemBars()
4040
ThemeUtils.THEME_SYSTEM -> {
4141
if (versionUntil(Build.VERSION_CODES.P)) {
42-
onPowerSaverModeChange()
42+
onPowerSaverModeChange(powerManager)
4343
} else {
4444
onUiModeConfigChange()
4545
}
@@ -48,22 +48,23 @@ abstract class BaseActivity : AppCompatActivity() {
4848
}
4949

5050
@RequiresApi(Build.VERSION_CODES.M)
51-
private fun onPowerSaverModeChange() {
52-
if (powerManager.isPowerSaveMode)
51+
override fun onPowerSaverModeChange(powerManager: PowerManager): Any {
52+
return if (powerManager.isPowerSaveMode)
5353
setDarkSystemBars()
5454
else
5555
setLightSystemBars()
5656
}
5757

5858
@RequiresApi(Build.VERSION_CODES.M)
59-
private fun onUiModeConfigChange() {
60-
when (resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) {
59+
override fun onUiModeConfigChange(): Any {
60+
return when (resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) {
6161
Configuration.UI_MODE_NIGHT_NO -> {
6262
setLightSystemBars()
6363
}
6464
Configuration.UI_MODE_NIGHT_YES -> {
6565
setDarkSystemBars()
6666
}
67+
else -> throw IllegalStateException()
6768
}
6869
}
6970

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
*
3+
* Copyright 2020 David Odari
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
6+
* in compliance with the License. You may obtain a copy of the License at
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
* Unless required by applicable law or agreed to in writing, software distributed under the License
9+
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
10+
* or implied. See the License for the specific language governing permissions and limitations under
11+
* the License.
12+
*
13+
**/
14+
package com.github.odaridavid.designpatterns.base
15+
16+
import android.os.PowerManager
17+
18+
/**
19+
* Listener for system initiated changes that affect how the ui will be rendered.
20+
* @param T expected output from system initiated change
21+
*/
22+
interface ISystemThemeChangeListener<out T> {
23+
/**
24+
* Called when there's a change in power saver settings
25+
*
26+
* @param powerManager an instance of PowerManager for power saver related operations
27+
*/
28+
fun onPowerSaverModeChange(powerManager: PowerManager): T
29+
30+
/**
31+
* Called when there's a change in theme initiated by the system
32+
* e.g Changing theme from the notification tray on Android Q and above
33+
*/
34+
fun onUiModeConfigChange(): T
35+
}

app/src/main/java/com/github/odaridavid/designpatterns/helpers/Extensions.kt

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ import android.app.Activity
1717
import android.content.Context
1818
import android.content.Intent
1919
import android.content.SharedPreferences
20-
import android.content.res.Configuration
2120
import android.os.Build
2221
import android.os.PowerManager
2322
import android.widget.Toast
2423
import androidx.preference.PreferenceManager
2524
import com.github.odaridavid.designpatterns.R
25+
import com.github.odaridavid.designpatterns.base.ISystemThemeChangeListener
2626
import com.github.odaridavid.designpatterns.helpers.SdkUtils.versionUntil
2727
import us.feras.mdv.MarkdownView
2828

@@ -35,45 +35,37 @@ inline fun <reified T> Activity.navigateTo(noinline intentExtras: ((Intent) -> U
3535
startActivity(intent)
3636
}
3737

38-
internal fun MarkdownView.loadWithKotlinCss(context: Context, filePath: String) {
38+
internal fun MarkdownView.loadWithKotlinCss(
39+
context: Context,
40+
filePath: String,
41+
systemThemeChangeListener: ISystemThemeChangeListener<String>
42+
) {
3943
loadMarkdownFile(
4044
filePath,
41-
getThemedCss(context)
45+
getThemedCss(context, systemThemeChangeListener)
4246
)
4347
}
4448

45-
internal fun getThemedCss(context: Context): String {
49+
internal fun getThemedCss(
50+
context: Context,
51+
systemThemeChangeListener: ISystemThemeChangeListener<String>
52+
): String {
4653
val sp = PreferenceManager.getDefaultSharedPreferences(context)
4754
return when (getCurrentTheme(context, sp)) {
4855
ThemeUtils.THEME_DARK -> DARK_KOTLIN_CSS_PATH
4956
ThemeUtils.THEME_LIGHT -> LIGHT_KOTLIN_CSS_PATH
5057
ThemeUtils.THEME_SYSTEM -> {
5158
if (versionUntil(Build.VERSION_CODES.P)) {
5259
val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
53-
onPowerSaverModeChange(powerManager)
60+
systemThemeChangeListener.onPowerSaverModeChange(powerManager)
5461
} else {
55-
onUiModeConfigChange(context)
62+
systemThemeChangeListener.onUiModeConfigChange()
5663
}
5764
}
5865
else -> LIGHT_KOTLIN_CSS_PATH
5966
}
6067
}
6168

62-
private fun onUiModeConfigChange(context: Context): String {
63-
return when (context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) {
64-
Configuration.UI_MODE_NIGHT_NO -> LIGHT_KOTLIN_CSS_PATH
65-
Configuration.UI_MODE_NIGHT_YES -> DARK_KOTLIN_CSS_PATH
66-
else -> LIGHT_KOTLIN_CSS_PATH
67-
}
68-
}
69-
70-
private fun onPowerSaverModeChange(powerManager: PowerManager): String {
71-
return if (powerManager.isPowerSaveMode)
72-
DARK_KOTLIN_CSS_PATH
73-
else
74-
LIGHT_KOTLIN_CSS_PATH
75-
}
76-
7769
internal fun getCurrentTheme(context: Context, sp: SharedPreferences?): String {
7870
return sp?.getString(context.getString(R.string.key_theme_preference), ThemeUtils.THEME_LIGHT)
7971
?: "default"

app/src/main/java/com/github/odaridavid/designpatterns/ui/DesignPatternDetailActivity.kt

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
package com.github.odaridavid.designpatterns.ui
22

3+
import android.content.res.Configuration
4+
import android.os.Build
35
import android.os.Bundle
6+
import android.os.PowerManager
7+
import androidx.annotation.RequiresApi
48
import com.github.odaridavid.designpatterns.base.BaseActivity
9+
import com.github.odaridavid.designpatterns.base.ISystemThemeChangeListener
510
import com.github.odaridavid.designpatterns.databinding.ActivityDesignPatternDetailBinding
11+
import com.github.odaridavid.designpatterns.helpers.DARK_KOTLIN_CSS_PATH
12+
import com.github.odaridavid.designpatterns.helpers.LIGHT_KOTLIN_CSS_PATH
613
import com.github.odaridavid.designpatterns.helpers.NavigationUtils
714
import com.github.odaridavid.designpatterns.helpers.loadWithKotlinCss
815
import com.github.odaridavid.designpatterns.models.DesignPattern
@@ -21,6 +28,26 @@ class DesignPatternDetailActivity : BaseActivity() {
2128

2229
supportActionBar?.setTitle(designPattern.name)
2330
binding.designPatternDescriptionTextView.text = getString(designPattern.description)
24-
binding.designPatternMarkdownView.loadWithKotlinCss(baseContext, designPattern.codeSample)
31+
binding.designPatternMarkdownView.loadWithKotlinCss(
32+
baseContext,
33+
designPattern.codeSample,
34+
this as ISystemThemeChangeListener<String>
35+
)
36+
}
37+
38+
@RequiresApi(Build.VERSION_CODES.M)
39+
override fun onPowerSaverModeChange(powerManager: PowerManager): String {
40+
super.onPowerSaverModeChange(powerManager)
41+
return if (powerManager.isPowerSaveMode) DARK_KOTLIN_CSS_PATH else LIGHT_KOTLIN_CSS_PATH
42+
}
43+
44+
@RequiresApi(Build.VERSION_CODES.M)
45+
override fun onUiModeConfigChange(): String {
46+
super.onUiModeConfigChange()
47+
return when (resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) {
48+
Configuration.UI_MODE_NIGHT_NO -> LIGHT_KOTLIN_CSS_PATH
49+
Configuration.UI_MODE_NIGHT_YES -> DARK_KOTLIN_CSS_PATH
50+
else -> LIGHT_KOTLIN_CSS_PATH
51+
}
2552
}
2653
}

app/src/main/java/com/github/odaridavid/designpatterns/ui/SettingsFragment.kt

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,36 @@
11
package com.github.odaridavid.designpatterns.ui
22

3+
import android.content.Context
34
import android.content.SharedPreferences
5+
import android.content.res.Configuration
46
import android.os.Build
57
import android.os.Bundle
8+
import android.os.PowerManager
69
import androidx.annotation.DrawableRes
710
import androidx.annotation.StringRes
811
import androidx.appcompat.content.res.AppCompatResources.getDrawable
912
import androidx.preference.ListPreference
1013
import androidx.preference.Preference
1114
import androidx.preference.PreferenceFragmentCompat
1215
import com.github.odaridavid.designpatterns.R
16+
import com.github.odaridavid.designpatterns.base.ISystemThemeChangeListener
1317
import com.github.odaridavid.designpatterns.helpers.SdkUtils
18+
import com.github.odaridavid.designpatterns.helpers.SdkUtils.versionUntil
1419
import com.github.odaridavid.designpatterns.helpers.ThemeUtils
1520
import com.github.odaridavid.designpatterns.helpers.ThemeUtils.THEME_DARK
1621
import com.github.odaridavid.designpatterns.helpers.ThemeUtils.THEME_LIGHT
1722
import com.github.odaridavid.designpatterns.helpers.ThemeUtils.THEME_SYSTEM
1823

1924
internal class SettingsFragment : PreferenceFragmentCompat(),
20-
SharedPreferences.OnSharedPreferenceChangeListener {
25+
SharedPreferences.OnSharedPreferenceChangeListener, ISystemThemeChangeListener<Int> {
2126

2227
private var themePreference: ListPreference? = null
2328
private val themePreferenceKey: String by lazy {
2429
getString(R.string.key_theme_preference)
2530
}
31+
private val powerManager: PowerManager by lazy {
32+
requireContext().getSystemService(Context.POWER_SERVICE) as PowerManager
33+
}
2634

2735
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
2836
setPreferencesFromResource(R.xml.preferences, rootKey)
@@ -76,7 +84,13 @@ internal class SettingsFragment : PreferenceFragmentCompat(),
7684
return when (themeValue) {
7785
THEME_LIGHT -> R.drawable.ic_day_black_24dp
7886
THEME_DARK -> R.drawable.ic_night_black_24dp
79-
THEME_SYSTEM -> R.drawable.ic_day_black_24dp
87+
THEME_SYSTEM -> {
88+
if (versionUntil(Build.VERSION_CODES.P)) {
89+
onPowerSaverModeChange(powerManager)
90+
} else {
91+
onUiModeConfigChange()
92+
}
93+
}
8094
else -> R.drawable.ic_day_black_24dp
8195
}
8296
}
@@ -97,6 +111,20 @@ internal class SettingsFragment : PreferenceFragmentCompat(),
97111
}
98112
}
99113

114+
@DrawableRes
115+
override fun onUiModeConfigChange(): Int {
116+
return when (requireContext().resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) {
117+
Configuration.UI_MODE_NIGHT_NO -> R.drawable.ic_day_black_24dp
118+
Configuration.UI_MODE_NIGHT_YES -> R.drawable.ic_night_black_24dp
119+
else -> R.drawable.ic_day_black_24dp
120+
}
121+
}
122+
123+
@DrawableRes
124+
override fun onPowerSaverModeChange(powerManager: PowerManager): Int {
125+
return if (powerManager.isPowerSaveMode) R.drawable.ic_night_black_24dp else R.drawable.ic_day_black_24dp
126+
}
127+
100128
companion object {
101129
const val DEFAULT_THEME_VALUE = "Light"
102130
}

whatsnew/whatsnew-en-GB

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1 @@
1-
- Fix code sample not switching to a dark theme on system-related theme change.
2-
- Rename System Default theme preference to Follow System on Devices running Android Q and above.
3-
- Minor bug fixes and improvements.
1+
- Enable theme settings icon changing on theme changes by the system.

0 commit comments

Comments
 (0)