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

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

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

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

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

* 删掉修改时的代码冗余

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

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

---------

Co-authored-by: ChanglePan <ncort@qq.com>
This commit is contained in:
5151561andChanglePan authored and GitHub committed 2026-03-20 00:31:01 +08:00
1 parent 34565bc8e0
commit 3e283cf7a3
4 files changed
+65 -6

No files matched your search

@@ -11,11 +11,13 @@ import io.legado.app.constant.EventBus
import io.legado.app.constant.Theme import io.legado.app.constant.Theme
import io.legado.app.help.config.OldThemeConfig import io.legado.app.help.config.OldThemeConfig
import io.legado.app.ui.theme.AppTheme 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.disableAutoFill
import io.legado.app.utils.fullScreen import io.legado.app.utils.fullScreen
import io.legado.app.utils.observeEvent import io.legado.app.utils.observeEvent
import io.legado.app.utils.setStatusBarColorAuto import io.legado.app.utils.setStatusBarColorAuto
import io.legado.app.utils.themeColor import io.legado.app.utils.themeColor
import io.legado.app.utils.toggleSystemBar
import io.legado.app.utils.windowSize import io.legado.app.utils.windowSize
abstract class BaseComposeActivity( abstract class BaseComposeActivity(
@@ -61,6 +63,8 @@ abstract class BaseComposeActivity(
true, true,
fullScreen fullScreen
) )
toggleSystemBar(AppConfig.showStatusBar)
} }
open fun upBackgroundImage() { open fun upBackgroundImage() {
@@ -75,6 +79,9 @@ abstract class BaseComposeActivity(
observeEvent<String>(EventBus.RECREATE) { observeEvent<String>(EventBus.RECREATE) {
recreate() recreate()
} }
observeEvent<Boolean>(EventBus.NOTIFY_MAIN) {
setupSystemBar()
}
} }
} }
@@ -1,7 +1,11 @@
package io.legado.app.ui.config package io.legado.app.ui.config
import android.content.SharedPreferences
import androidx.compose.runtime.MutableState import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf 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.getPrefBoolean
import io.legado.app.utils.getPrefInt import io.legado.app.utils.getPrefInt
import io.legado.app.utils.getPrefLong import io.legado.app.utils.getPrefLong
@@ -14,14 +18,39 @@ import splitties.init.appCtx
import kotlin.properties.ReadWriteProperty import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty import kotlin.reflect.KProperty
interface PrefDelegate<T> : ReadWriteProperty<Any?, T> {
fun dispose()
}
fun <T> prefDelegate( fun <T> prefDelegate(
key: String, key: String,
defaultValue: T, defaultValue: T,
lifecycleOwner: LifecycleOwner? = null,
onValueChange: ((T) -> Unit)? = null onValueChange: ((T) -> Unit)? = null
): ReadWriteProperty<Any?, T> { ): PrefDelegate<T> {
return object : ReadWriteProperty<Any?, T> { return object : PrefDelegate<T>, SharedPreferences.OnSharedPreferenceChangeListener, DefaultLifecycleObserver {
private var _value: MutableState<T> = mutableStateOf(readInitialValue()) 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") @Suppress("UNCHECKED_CAST")
private fun readInitialValue(): T { private fun readInitialValue(): T {
return when (defaultValue) { return when (defaultValue) {
@@ -49,5 +78,15 @@ fun <T> prefDelegate(
onValueChange?.invoke(value) 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.CrashLogsDialog
import io.legado.app.ui.about.UpdateDialog import io.legado.app.ui.about.UpdateDialog
import io.legado.app.ui.book.read.ReadBookActivity 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.welcome.WelcomeActivity
import io.legado.app.ui.widget.dialog.TextDialog import io.legado.app.ui.widget.dialog.TextDialog
import io.legado.app.utils.getPrefBoolean import io.legado.app.utils.getPrefBoolean
@@ -73,7 +74,7 @@ open class MainActivity : BaseComposeActivity() {
override fun Content() { override fun Content() {
val orientation = resources.configuration.orientation val orientation = resources.configuration.orientation
val smallestWidthDp = resources.configuration.smallestScreenWidthDp val smallestWidthDp = resources.configuration.smallestScreenWidthDp
val tabletInterface = AppConfig.tabletInterface val tabletInterface = MainConfig.tabletInterface
val useRail = when (tabletInterface) { val useRail = when (tabletInterface) {
"always" -> true "always" -> true
@@ -137,6 +137,7 @@ fun MainScreen(
} }
} }
) { ) {
val labelVisibilityMode = MainConfig.labelVisibilityMode
destinations.forEachIndexed { index, destination -> destinations.forEachIndexed { index, destination ->
val selected = pagerState.currentPage == index val selected = pagerState.currentPage == index
WideNavigationRailItem( WideNavigationRailItem(
@@ -150,7 +151,9 @@ fun MainScreen(
icon = { icon = {
NavigationIcon(destination, selected, uiState.upBooksCount) 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 blurAlpha = GlassDefaults.DefaultBlurAlpha
) )
) { ) {
val labelVisibilityMode = MainConfig.labelVisibilityMode
val alwaysShowLabel = when (labelVisibilityMode) {
"labeled" -> true
"selected" -> false
"unlabeled" -> false
else -> false
}
destinations.forEachIndexed { index, destination -> destinations.forEachIndexed { index, destination ->
val selected = pagerState.currentPage == index val selected = pagerState.currentPage == index
NavigationBarItem( NavigationBarItem(
@@ -187,8 +197,10 @@ fun MainScreen(
blurAlpha = GlassDefaults.ThickBlurAlpha blurAlpha = GlassDefaults.ThickBlurAlpha
), ),
), ),
label = { Text(stringResource(destination.labelId)) }, label = if (labelVisibilityMode != "unlabeled") {
alwaysShowLabel = false { Text(stringResource(destination.labelId)) }
} else null,
alwaysShowLabel = alwaysShowLabel
) )
} }
} }