Преглед изворни кода

[修复] 修复外观设置'不生效/重启才生效'问题 (#736) @5151561

* fix: 修复配置代理由于未监听 SharePreferences 导致设置无法实时生效的问题

* fix: 导航栏支持设置中的标签显示模式(始终显示/选中显示/不显示) 不生效问题

* fix: 修复状态栏显隐开关无效的问题

* fix: 修复平板界面状态不及时响应问题

* 删掉修改时的代码冗余

* 将标签设置的参数读取移到循环外

* 按照AI的建议,通过引入 LifecycleOwner支持和显式的 dispose()方法,实现了 SharedPreferences监听器的自动与手动注销,解决了内存泄漏隐患并保持了实时同步特性。

---------

Co-authored-by: ChanglePan <ncort@qq.com>
5151561 пре 7 месеци
родитељ
комит
3e283cf7a3

+ 7 - 0
app/src/main/java/io/legado/app/base/BaseComposeActivity.kt

@@ -11,11 +11,13 @@ import io.legado.app.constant.EventBus
 import io.legado.app.constant.Theme
 import io.legado.app.help.config.OldThemeConfig
 import io.legado.app.ui.theme.AppTheme
+import io.legado.app.help.config.AppConfig
 import io.legado.app.utils.disableAutoFill
 import io.legado.app.utils.fullScreen
 import io.legado.app.utils.observeEvent
 import io.legado.app.utils.setStatusBarColorAuto
 import io.legado.app.utils.themeColor
+import io.legado.app.utils.toggleSystemBar
 import io.legado.app.utils.windowSize
 
 abstract class BaseComposeActivity(
@@ -61,6 +63,8 @@ abstract class BaseComposeActivity(
             true,
             fullScreen
         )
+
+        toggleSystemBar(AppConfig.showStatusBar)
     }
 
     open fun upBackgroundImage() {
@@ -75,6 +79,9 @@ abstract class BaseComposeActivity(
         observeEvent<String>(EventBus.RECREATE) {
             recreate()
         }
+        observeEvent<Boolean>(EventBus.NOTIFY_MAIN) {
+            setupSystemBar()
+        }
     }
 
 }

+ 41 - 2
app/src/main/java/io/legado/app/ui/config/PrefDelegate.kt

@@ -1,7 +1,11 @@
 package io.legado.app.ui.config
 
+import android.content.SharedPreferences
 import androidx.compose.runtime.MutableState
 import androidx.compose.runtime.mutableStateOf
+import androidx.lifecycle.DefaultLifecycleObserver
+import androidx.lifecycle.LifecycleOwner
+import io.legado.app.utils.defaultSharedPreferences
 import io.legado.app.utils.getPrefBoolean
 import io.legado.app.utils.getPrefInt
 import io.legado.app.utils.getPrefLong
@@ -14,14 +18,39 @@ import splitties.init.appCtx
 import kotlin.properties.ReadWriteProperty
 import kotlin.reflect.KProperty
 
+interface PrefDelegate<T> : ReadWriteProperty<Any?, T> {
+    fun dispose()
+}
+
 fun <T> prefDelegate(
     key: String,
     defaultValue: T,
+    lifecycleOwner: LifecycleOwner? = null,
     onValueChange: ((T) -> Unit)? = null
-): ReadWriteProperty<Any?, T> {
-    return object : ReadWriteProperty<Any?, T> {
+): PrefDelegate<T> {
+    return object : PrefDelegate<T>, SharedPreferences.OnSharedPreferenceChangeListener, DefaultLifecycleObserver {
         private var _value: MutableState<T> = mutableStateOf(readInitialValue())
 
+        init {
+            if (lifecycleOwner != null) {
+                lifecycleOwner.lifecycle.addObserver(this)
+            } else {
+                appCtx.defaultSharedPreferences.registerOnSharedPreferenceChangeListener(this)
+            }
+        }
+
+        override fun onCreate(owner: LifecycleOwner) {
+            appCtx.defaultSharedPreferences.registerOnSharedPreferenceChangeListener(this)
+        }
+
+        override fun onDestroy(owner: LifecycleOwner) {
+            dispose()
+        }
+
+        override fun dispose() {
+            appCtx.defaultSharedPreferences.unregisterOnSharedPreferenceChangeListener(this)
+        }
+
         @Suppress("UNCHECKED_CAST")
         private fun readInitialValue(): T {
             return when (defaultValue) {
@@ -49,5 +78,15 @@ fun <T> prefDelegate(
                 onValueChange?.invoke(value)
             }
         }
+
+        override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, changedKey: String?) {
+            if (changedKey == key) {
+                val newValue = readInitialValue()
+                if (_value.value != newValue) {
+                    _value.value = newValue
+                    onValueChange?.invoke(newValue)
+                }
+            }
+        }
     }
 }

+ 2 - 1
app/src/main/java/io/legado/app/ui/main/MainActivity.kt

@@ -23,6 +23,7 @@ import io.legado.app.service.WebService
 import io.legado.app.ui.about.CrashLogsDialog
 import io.legado.app.ui.about.UpdateDialog
 import io.legado.app.ui.book.read.ReadBookActivity
+import io.legado.app.ui.config.mainConfig.MainConfig
 import io.legado.app.ui.welcome.WelcomeActivity
 import io.legado.app.ui.widget.dialog.TextDialog
 import io.legado.app.utils.getPrefBoolean
@@ -73,7 +74,7 @@ open class MainActivity : BaseComposeActivity() {
     override fun Content() {
         val orientation = resources.configuration.orientation
         val smallestWidthDp = resources.configuration.smallestScreenWidthDp
-        val tabletInterface = AppConfig.tabletInterface
+        val tabletInterface = MainConfig.tabletInterface
 
         val useRail = when (tabletInterface) {
             "always" -> true

+ 15 - 3
app/src/main/java/io/legado/app/ui/main/MainScreen.kt

@@ -137,6 +137,7 @@ fun MainScreen(
                     }
                 }
             ) {
+                val labelVisibilityMode = MainConfig.labelVisibilityMode
                 destinations.forEachIndexed { index, destination ->
                     val selected = pagerState.currentPage == index
                     WideNavigationRailItem(
@@ -150,7 +151,9 @@ fun MainScreen(
                         icon = {
                             NavigationIcon(destination, selected, uiState.upBooksCount)
                         },
-                        label = { Text(stringResource(destination.labelId)) }
+                        label = if (labelVisibilityMode != "unlabeled") {
+                            { Text(stringResource(destination.labelId)) }
+                        } else null
                     )
                 }
             }
@@ -169,6 +172,13 @@ fun MainScreen(
                             blurAlpha = GlassDefaults.DefaultBlurAlpha
                         )
                     ) {
+                        val labelVisibilityMode = MainConfig.labelVisibilityMode
+                        val alwaysShowLabel = when (labelVisibilityMode) {
+                            "labeled" -> true
+                            "selected" -> false
+                            "unlabeled" -> false
+                            else -> false
+                        }
                         destinations.forEachIndexed { index, destination ->
                             val selected = pagerState.currentPage == index
                             NavigationBarItem(
@@ -187,8 +197,10 @@ fun MainScreen(
                                         blurAlpha = GlassDefaults.ThickBlurAlpha
                                     ),
                                 ),
-                                label = { Text(stringResource(destination.labelId)) },
-                                alwaysShowLabel = false
+                                label = if (labelVisibilityMode != "unlabeled") {
+                                    { Text(stringResource(destination.labelId)) }
+                                } else null,
+                                alwaysShowLabel = alwaysShowLabel
                             )
                         }
                     }