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

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

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

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

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

* 删掉修改时的代码冗余

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

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

---------

Co-authored-by: ChanglePan <ncort@qq.com>
This commit is contained in:
5151561
2026-03-20 00:31:01 +08:00
committed by GitHub
co-authored by ChanglePan
parent 34565bc8e0
commit 3e283cf7a3
4 changed files with 65 additions and 6 deletions
@@ -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()
}
}
}
@@ -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)
}
}
}
}
}
@@ -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
@@ -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
)
}
}