[优化] 增加控件

This commit is contained in:
HapeLee committed 2026-03-31 07:55:21 +08:00
1 parent 01fb34a1bd
commit 733312fe23
14 files changed
+206 -117

No files matched your search

@@ -295,7 +295,6 @@ fun ExploreShowScreen(
state = hazeState state = hazeState
), ),
title = selectedTitle ?: title, title = selectedTitle ?: title,
colors = GlassTopAppBarDefaults.glassColors(),
navigationIcon = { navigationIcon = {
TopbarNavigationButton(onClick = onBack) TopbarNavigationButton(onClick = onBack)
}, },
@@ -137,23 +137,28 @@ fun ThemeConfigScreen(
.verticalScroll(rememberScrollState()) .verticalScroll(rememberScrollState())
.padding(16.dp) .padding(16.dp)
) { ) {
val composeEngine = remember { ThemeConfig.composeEngine }
val isMiuixEngine =
remember(composeEngine) { ThemeResolver.isMiuixEngine(composeEngine) }
val isDarkTheme = when (selectedThemeMode) { val isDarkTheme = when (selectedThemeMode) {
"1" -> false "1" -> false
"2" -> true "2" -> true
else -> isSystemInDarkTheme() else -> isSystemInDarkTheme()
} }
Column( if (!isMiuixEngine) {
horizontalAlignment = Alignment.CenterHorizontally, Column(
modifier = Modifier.fillMaxWidth() horizontalAlignment = Alignment.CenterHorizontally,
) { modifier = Modifier.fillMaxWidth()
ThemeCard( ) {
context = context, ThemeCard(
value = selectedTheme, context = context,
isDark = isDarkTheme, value = selectedTheme,
isAmoled = ThemeConfig.isPureBlack, isDark = isDarkTheme,
paletteStyle = ThemeConfig.paletteStyle isAmoled = ThemeConfig.isPureBlack,
) paletteStyle = ThemeConfig.paletteStyle
)
}
} }
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
@@ -165,46 +170,62 @@ fun ThemeConfigScreen(
} }
SplicedColumnGroup(title = stringResource(R.string.theme)) { SplicedColumnGroup(title = stringResource(R.string.theme)) {
ThemeModeSelector( if (isMiuixEngine) {
selectedMode = selectedThemeMode, DropdownListSettingItem(
onModeSelected = { mode -> title = stringResource(R.string.theme_mode),
selectedThemeMode = mode selectedValue = selectedThemeMode,
ThemeConfig.themeMode = mode displayEntries = stringArrayResource(R.array.theme_mode),
OldThemeConfig.applyDayNight(context) entryValues = stringArrayResource(R.array.theme_mode_v),
} onValueChange = { mode ->
) selectedThemeMode = mode
ThemeConfig.themeMode = mode
OldThemeConfig.applyDayNight(context)
}
)
} else {
ThemeModeSelector(
selectedMode = selectedThemeMode,
onModeSelected = { mode ->
selectedThemeMode = mode
ThemeConfig.themeMode = mode
OldThemeConfig.applyDayNight(context)
}
)
}
Spacer(modifier = Modifier.height(16.dp)) if (!isMiuixEngine) {
Spacer(modifier = Modifier.height(16.dp))
ThemeColorSelector( ThemeColorSelector(
context = context, context = context,
themes = themes, themes = themes,
selectedTheme = selectedTheme, selectedTheme = selectedTheme,
isDark = isDarkTheme, isDark = isDarkTheme,
isAmoled = ThemeConfig.isPureBlack, isAmoled = ThemeConfig.isPureBlack,
paletteStyle = ThemeConfig.paletteStyle, paletteStyle = ThemeConfig.paletteStyle,
onThemeSelected = { theme -> onThemeSelected = { theme ->
if (theme == "13") { if (theme == "13") {
val hasLightBg = !ThemeConfig.bgImageLight.isNullOrEmpty() val hasLightBg = !ThemeConfig.bgImageLight.isNullOrEmpty()
val hasDarkBg = !ThemeConfig.bgImageDark.isNullOrEmpty() val hasDarkBg = !ThemeConfig.bgImageDark.isNullOrEmpty()
if (!hasLightBg || !hasDarkBg) { if (!hasLightBg || !hasDarkBg) {
context.toastOnUi(R.string.transparent_theme_alarm) context.toastOnUi(R.string.transparent_theme_alarm)
return@ThemeColorSelector return@ThemeColorSelector
} else {
AppConfig.containerOpacity = 0
}
}
val oldTheme = selectedTheme
selectedTheme = theme
ThemeConfig.appTheme = theme
val isDynamicSwitch = (oldTheme == "12" || theme == "12")
if (isDynamicSwitch) {
showRestartDialog = true
} else { } else {
AppConfig.containerOpacity = 0 postEvent(EventBus.RECREATE, "")
} }
} }
val oldTheme = selectedTheme )
selectedTheme = theme }
ThemeConfig.appTheme = theme
val isDynamicSwitch = (oldTheme == "12" || theme == "12")
if (isDynamicSwitch) {
showRestartDialog = true
} else {
postEvent(EventBus.RECREATE, "")
}
}
)
} }
SplicedColumnGroup { SplicedColumnGroup {
@@ -240,7 +261,7 @@ fun ThemeConfigScreen(
R.string.font_scale_summary, R.string.font_scale_summary,
AppContextWrapper.getFontScale(context) AppContextWrapper.getFontScale(context)
), ),
value = fontScaleValue.value, value = fontScaleValue.floatValue,
defaultValue = 10f, defaultValue = 10f,
valueRange = 8f..16f, valueRange = 8f..16f,
steps = 7, steps = 7,
@@ -254,7 +254,11 @@ fun MainScreen(
labelString = stringResource(destination.labelId), labelString = stringResource(destination.labelId),
miuixIcon = if (selected) destination.miuixSelectedIcon else destination.miuixIcon, miuixIcon = if (selected) destination.miuixSelectedIcon else destination.miuixIcon,
m3Icon = { m3Icon = {
if (selected) destination.m3SelectedIcon else destination.m3Icon NavigationIcon(
destination = destination,
selected = selected,
upBooksCount = uiState.upBooksCount
)
}, },
m3IndicatorColor = GlassDefaults.glassColor( m3IndicatorColor = GlassDefaults.glassColor(
noBlurColor = MaterialTheme.colorScheme.secondaryContainer, noBlurColor = MaterialTheme.colorScheme.secondaryContainer,
@@ -42,7 +42,6 @@ import androidx.compose.material3.ListItem
import androidx.compose.material3.ListItemDefaults import androidx.compose.material3.ListItemDefaults
import androidx.compose.material3.LocalMinimumInteractiveComponentSize import androidx.compose.material3.LocalMinimumInteractiveComponentSize
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedCard
import androidx.compose.material3.TextButton import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.CompositionLocalProvider
@@ -142,6 +141,8 @@ fun ExploreScreen(
} }
} }
val composeEngine = ThemeResolver.isMiuixEngine(composeEngine)
ListScaffold( ListScaffold(
title = stringResource(R.string.discovery), title = stringResource(R.string.discovery),
state = uiState, state = uiState,
@@ -201,7 +202,8 @@ fun ExploreScreen(
} }
}, },
onRefresh = { viewModel.refreshExploreKinds(item) }, onRefresh = { viewModel.refreshExploreKinds(item) },
onDelete = { sourceToDelete = item } onDelete = { sourceToDelete = item },
isMiuix = composeEngine
) )
} }
@@ -232,7 +234,8 @@ fun ExploreScreen(
putExtra("exploreUrl", kind.url) putExtra("exploreUrl", kind.url)
} }
} }
} },
isMiuix = composeEngine
) )
} }
@@ -268,7 +271,8 @@ fun ExploreScreen(
uiState.items.indexOfFirst { it.bookSourceUrl == item.bookSourceUrl } uiState.items.indexOfFirst { it.bookSourceUrl == item.bookSourceUrl }
if (index >= 0) listState.animateScrollToItem(index) if (index >= 0) listState.animateScrollToItem(index)
} }
} },
isMiuix = composeEngine
) )
} }
} }
@@ -345,25 +349,25 @@ fun ExploreSourceHeader(
onLogin: () -> Unit, onLogin: () -> Unit,
onRefresh: () -> Unit, onRefresh: () -> Unit,
onDelete: () -> Unit, onDelete: () -> Unit,
isMiuix: Boolean,
) { ) {
var showMenu by remember { mutableStateOf(false) } var showMenu by remember { mutableStateOf(false) }
val rotation by animateFloatAsState(if (isExpanded) 90f else 0f, label = "rotation") val rotation by animateFloatAsState(if (isExpanded) 90f else 0f, label = "rotation")
val composeEngine = ThemeResolver.isMiuixEngine(composeEngine)
val containerColor by animateColorAsState( val containerColor by animateColorAsState(
targetValue = if (isExpanded) targetValue = if (isExpanded)
if (composeEngine) MiuixTheme.colorScheme.secondaryContainer else MaterialTheme.colorScheme.secondaryContainer if (isMiuix) MiuixTheme.colorScheme.secondaryContainer else MaterialTheme.colorScheme.secondaryContainer
else else
if (composeEngine) MiuixTheme.colorScheme.surfaceContainer else MaterialTheme.colorScheme.surfaceContainerLow, if (isMiuix) MiuixTheme.colorScheme.surfaceContainer else MaterialTheme.colorScheme.surfaceContainerLow,
animationSpec = tween(durationMillis = 200, easing = FastOutSlowInEasing), animationSpec = tween(durationMillis = 200, easing = FastOutSlowInEasing),
label = "CardColor" label = "CardColor"
) )
val contentColor by animateColorAsState( val contentColor by animateColorAsState(
targetValue = if (isExpanded) targetValue = if (isExpanded)
if (composeEngine) MiuixTheme.colorScheme.primary else MaterialTheme.colorScheme.primary if (isMiuix) MiuixTheme.colorScheme.primary else MaterialTheme.colorScheme.primary
else else
if (composeEngine) MiuixTheme.colorScheme.onSurface else MaterialTheme.colorScheme.onSurface, if (isMiuix) MiuixTheme.colorScheme.onSurface else MaterialTheme.colorScheme.onSurface,
animationSpec = tween(durationMillis = 200, easing = FastOutSlowInEasing), animationSpec = tween(durationMillis = 200, easing = FastOutSlowInEasing),
label = "CardColor" label = "CardColor"
) )
@@ -461,11 +465,11 @@ fun ExploreSourceHeader(
@Composable @Composable
fun ExploreStickyCard( fun ExploreStickyCard(
item: BookSourcePart, item: BookSourcePart,
onClick: () -> Unit onClick: () -> Unit,
isMiuix: Boolean,
) { ) {
TextCard( TextCard(
text = item.bookSourceName, text = item.bookSourceName,
backgroundColor = MaterialTheme.colorScheme.surfaceContainerHigh,
textStyle = LegadoTheme.typography.labelLarge, textStyle = LegadoTheme.typography.labelLarge,
horizontalPadding = 8.dp, horizontalPadding = 8.dp,
verticalPadding = 6.dp, verticalPadding = 6.dp,
@@ -478,8 +482,29 @@ fun ExploreKindItem(
kind: ExploreKind, kind: ExploreKind,
isClickable: Boolean, isClickable: Boolean,
onClick: () -> Unit, onClick: () -> Unit,
modifier: Modifier = Modifier modifier: Modifier = Modifier,
isMiuix: Boolean,
) { ) {
val color = if (isMiuix)
MiuixTheme.colorScheme.surfaceContainer
else
MaterialTheme.colorScheme.secondaryContainer
val contentColor = if (isMiuix)
MiuixTheme.colorScheme.onSurface
else
MaterialTheme.colorScheme.secondary
val unClickBackColor = if (isMiuix)
MiuixTheme.colorScheme.surfaceContainer
else
MaterialTheme.colorScheme.surface
val unClickColor = if (isMiuix)
MiuixTheme.colorScheme.disabledOnSurface
else
MaterialTheme.colorScheme.primary
CompositionLocalProvider( CompositionLocalProvider(
LocalMinimumInteractiveComponentSize provides Dp.Unspecified LocalMinimumInteractiveComponentSize provides Dp.Unspecified
) { ) {
@@ -490,19 +515,19 @@ fun ExploreKindItem(
GlassCard( GlassCard(
onClick = onClick, onClick = onClick,
shape = shape, shape = shape,
containerColor = MaterialTheme.colorScheme.secondaryContainer.copy(alpha = 0.6f), containerColor = color.copy(alpha = 0.6f),
contentColor = MaterialTheme.colorScheme.onSecondaryContainer, contentColor = contentColor,
modifier = modifier modifier = modifier
) { ) {
KindText(kind) KindText(kind)
} }
} else { } else {
OutlinedCard( GlassCard(
shape = shape, shape = shape,
colors = CardDefaults.outlinedCardColors( containerColor = unClickBackColor.copy(alpha = 0.6f),
contentColor = MaterialTheme.colorScheme.primary contentColor = unClickColor,
), modifier = modifier,
modifier = modifier border = CardDefaults.outlinedCardBorder()
) { ) {
KindText(kind) KindText(kind)
} }
@@ -1,6 +1,6 @@
package io.legado.app.ui.widget.components.icon package io.legado.app.ui.widget.components
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@@ -8,18 +8,20 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import io.legado.app.ui.theme.LegadoTheme.composeEngine import io.legado.app.ui.theme.LegadoTheme.composeEngine
import io.legado.app.ui.theme.ThemeResolver import io.legado.app.ui.theme.ThemeResolver
import top.yukonga.miuix.kmp.theme.LocalContentColor import androidx.compose.material3.LocalContentColor as MaterialLocalContentColor
import top.yukonga.miuix.kmp.basic.Icon as MiuixIcon import top.yukonga.miuix.kmp.basic.Icon as MiuixIcon
import top.yukonga.miuix.kmp.theme.LocalContentColor as MiuixLocalContentColor
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable @Composable
fun AppIcon( fun AppIcon(
imageVector: ImageVector, imageVector: ImageVector,
contentDescription: String?, contentDescription: String?,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
tint: Color = LocalContentColor.current, tint: Color = currentContentColor(),
) { ) {
if (ThemeResolver.isMiuixEngine(composeEngine)) { val isMiuix = ThemeResolver.isMiuixEngine(composeEngine)
if (isMiuix) {
MiuixIcon( MiuixIcon(
imageVector = imageVector, imageVector = imageVector,
contentDescription = contentDescription, contentDescription = contentDescription,
@@ -34,4 +36,14 @@ fun AppIcon(
tint = tint tint = tint
) )
} }
}
@Composable
fun currentContentColor(): Color {
val isMiuix = ThemeResolver.isMiuixEngine(composeEngine)
return if (isMiuix) {
MiuixLocalContentColor.current
} else {
MaterialLocalContentColor.current
}
} }
@@ -7,7 +7,6 @@ import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FabPosition import androidx.compose.material3.FabPosition
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
import androidx.compose.material3.ScaffoldDefaults import androidx.compose.material3.ScaffoldDefaults
import androidx.compose.material3.contentColorFor import androidx.compose.material3.contentColorFor
@@ -35,7 +34,7 @@ fun AppScaffold(
snackbarHost: @Composable () -> Unit = {}, snackbarHost: @Composable () -> Unit = {},
floatingActionButton: @Composable () -> Unit = {}, floatingActionButton: @Composable () -> Unit = {},
floatingActionButtonPosition: FabPosition = FabPosition.End, floatingActionButtonPosition: FabPosition = FabPosition.End,
contentColor: Color = contentColorFor(MaterialTheme.colorScheme.background), contentColor: Color = contentColorFor(MiuixTheme.colorScheme.surface),
contentWindowInsets: WindowInsets = ScaffoldDefaults.contentWindowInsets, contentWindowInsets: WindowInsets = ScaffoldDefaults.contentWindowInsets,
content: @Composable (PaddingValues) -> Unit content: @Composable (PaddingValues) -> Unit
) { ) {
@@ -56,7 +55,9 @@ fun AppScaffold(
MiuixTheme.colorScheme.surface MiuixTheme.colorScheme.surface
} }
CompositionLocalProvider(LocalHazeState provides hazeState) { CompositionLocalProvider(
LocalHazeState provides if (ThemeConfig.enableBlur) hazeState else null
) {
when { when {
ThemeResolver.isMiuixEngine(composeEngine) -> { ThemeResolver.isMiuixEngine(composeEngine) -> {
val miuixFabPosition = when (floatingActionButtonPosition) { val miuixFabPosition = when (floatingActionButtonPosition) {
@@ -7,7 +7,6 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
@@ -18,7 +17,11 @@ import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import io.legado.app.ui.theme.LegadoTheme import io.legado.app.ui.theme.LegadoTheme
import io.legado.app.ui.theme.LegadoTheme.composeEngine
import io.legado.app.ui.theme.ThemeResolver
import io.legado.app.ui.widget.components.AnimatedTextLine import io.legado.app.ui.widget.components.AnimatedTextLine
import io.legado.app.ui.widget.components.AppIcon
import top.yukonga.miuix.kmp.theme.MiuixTheme
@OptIn(ExperimentalMaterial3ExpressiveApi::class) @OptIn(ExperimentalMaterial3ExpressiveApi::class)
@@ -28,8 +31,8 @@ fun TextCard(
text: String, text: String,
icon: ImageVector? = null, icon: ImageVector? = null,
onClick: (() -> Unit)? = null, onClick: (() -> Unit)? = null,
backgroundColor: Color = MaterialTheme.colorScheme.primaryContainer, backgroundColor: Color? = null,
contentColor: Color = MaterialTheme.colorScheme.onPrimaryContainer, contentColor: Color? = null,
cornerRadius: Dp = 8.dp, cornerRadius: Dp = 8.dp,
horizontalPadding: Dp = 8.dp, horizontalPadding: Dp = 8.dp,
verticalPadding: Dp = 2.dp, verticalPadding: Dp = 2.dp,
@@ -37,11 +40,26 @@ fun TextCard(
spacing: Dp = 4.dp, spacing: Dp = 4.dp,
textStyle: TextStyle = LegadoTheme.typography.labelSmallEmphasized textStyle: TextStyle = LegadoTheme.typography.labelSmallEmphasized
) { ) {
val isMiuix = ThemeResolver.isMiuixEngine(composeEngine)
val defaultBackground = if (isMiuix)
MiuixTheme.colorScheme.surfaceContainer
else
MaterialTheme.colorScheme.primaryContainer
val defaultContent = if (isMiuix)
MiuixTheme.colorScheme.onSurface
else
MaterialTheme.colorScheme.primary
val finalBackgroundColor = backgroundColor ?: defaultBackground
val finalContentColor = contentColor ?: defaultContent
NormalCard( NormalCard(
modifier = modifier, modifier = modifier,
shape = RoundedCornerShape(cornerRadius), shape = RoundedCornerShape(cornerRadius),
containerColor = backgroundColor, containerColor = finalBackgroundColor,
contentColor = contentColor, contentColor = finalContentColor,
onClick = onClick onClick = onClick
) { ) {
Row( Row(
@@ -53,10 +71,10 @@ fun TextCard(
) { ) {
if (icon != null) { if (icon != null) {
Icon( AppIcon(
imageVector = icon, imageVector = icon,
contentDescription = null, contentDescription = null,
tint = contentColor, tint = finalContentColor,
modifier = Modifier.size(iconSize) modifier = Modifier.size(iconSize)
) )
Spacer(modifier = Modifier.width(spacing)) Spacer(modifier = Modifier.width(spacing))
@@ -65,7 +83,7 @@ fun TextCard(
AnimatedTextLine( AnimatedTextLine(
text = text, text = text,
style = textStyle, style = textStyle,
color = contentColor color = finalContentColor
) )
} }
} }
@@ -5,7 +5,6 @@ import androidx.compose.animation.expandVertically
import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut import androidx.compose.animation.fadeOut
import androidx.compose.animation.shrinkVertically import androidx.compose.animation.shrinkVertically
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.RowScope
@@ -17,16 +16,12 @@ import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material.icons.filled.Search import androidx.compose.material.icons.filled.Search
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.lerp
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import io.legado.app.ui.widget.components.AnimatedTextLine import io.legado.app.ui.widget.components.AnimatedTextLine
import io.legado.app.ui.widget.components.SearchBarSection import io.legado.app.ui.widget.components.SearchBarSection
@@ -58,19 +53,10 @@ fun <T> DynamicTopAppBar(
var showMenu by remember { mutableStateOf(false) } var showMenu by remember { mutableStateOf(false) }
val isSelecting = state.selectedIds.isNotEmpty() val isSelecting = state.selectedIds.isNotEmpty()
val containerColor = GlassTopAppBarDefaults.containerColor()
val scrolledColor = GlassTopAppBarDefaults.scrolledContainerColor()
val animatedColor by remember(scrollBehavior, containerColor, scrolledColor) {
derivedStateOf {
lerp(containerColor, scrolledColor, scrollBehavior.collapsedFraction)
}
}
GlassMediumFlexibleTopAppBar( GlassMediumFlexibleTopAppBar(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth(),
.background(animatedColor),
title = when { title = when {
state.isLoading -> "请稍后..." state.isLoading -> "请稍后..."
isSelecting -> "已选择 ${state.selectedIds.size}/${state.items.size}" isSelecting -> "已选择 ${state.selectedIds.size}/${state.items.size}"
@@ -117,10 +103,6 @@ fun <T> DynamicTopAppBar(
} }
}, },
scrollBehavior = scrollBehavior, scrollBehavior = scrollBehavior,
colors = TopAppBarDefaults.topAppBarColors(
containerColor = Color.Transparent,
scrolledContainerColor = Color.Transparent
),
bottomContent = { bottomContent = {
AnimatedVisibility( AnimatedVisibility(
visible = state.isSearch && !isSelecting, visible = state.isSearch && !isSelecting,
@@ -1,5 +1,6 @@
package io.legado.app.ui.widget.components.topbar package io.legado.app.ui.widget.components.topbar
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.RowScope
@@ -13,6 +14,7 @@ import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.lerp
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import io.legado.app.ui.config.themeConfig.ThemeConfig import io.legado.app.ui.config.themeConfig.ThemeConfig
import io.legado.app.ui.theme.LegadoTheme import io.legado.app.ui.theme.LegadoTheme
@@ -35,28 +37,54 @@ fun GlassMediumFlexibleTopAppBar(
scrollBehavior: GlassTopAppBarScrollBehavior? = null, scrollBehavior: GlassTopAppBarScrollBehavior? = null,
navigationIcon: @Composable () -> Unit = {}, navigationIcon: @Composable () -> Unit = {},
actions: @Composable RowScope.() -> Unit = {}, actions: @Composable RowScope.() -> Unit = {},
colors: TopAppBarColors = GlassTopAppBarDefaults.glassColors(),
bottomContent: @Composable (ColumnScope.() -> Unit)? = null bottomContent: @Composable (ColumnScope.() -> Unit)? = null
) { ) {
val hazeState = LocalHazeState.current val hazeState = LocalHazeState.current
val composeEngine = LegadoTheme.composeEngine
val isMiuix = ThemeResolver.isMiuixEngine(composeEngine)
val containerColor = if (!isMiuix) {
GlassTopAppBarDefaults.containerColor()
} else {
GlassTopAppBarDefaults.getMiuixAppBarColor()
}
val scrolledColor = if (!isMiuix) {
GlassTopAppBarDefaults.scrolledContainerColor()
} else {
GlassTopAppBarDefaults.getMiuixAppBarColor()
}
val animatedColor = if (!isMiuix) {
val fraction = scrollBehavior?.collapsedFraction ?: 0f
lerp(containerColor, scrolledColor, fraction)
} else {
containerColor
}
val finalModifier = if (hazeState != null) { val finalModifier = if (hazeState != null) {
modifier.responsiveHazeEffect(state = hazeState) modifier.responsiveHazeEffect(state = hazeState)
} else { } else {
modifier modifier.background(color = animatedColor)
} }
val composeEngine = LegadoTheme.composeEngine val transparentColors = TopAppBarDefaults.topAppBarColors(
containerColor = Color.Transparent,
scrolledContainerColor = Color.Transparent
)
Column(modifier = finalModifier) { Column(
modifier = finalModifier
) {
when { when {
ThemeResolver.isMiuixEngine(composeEngine) -> { isMiuix -> {
MiuixTopAppBar( MiuixTopAppBar(
modifier = Modifier, modifier = Modifier,
title = title, title = title,
navigationIcon = navigationIcon, navigationIcon = navigationIcon,
actions = actions, actions = actions,
color = GlassTopAppBarDefaults.getMiuixAppBarColor(), color = Color.Transparent, // 内部强制透明,透出 Column 背景
scrollBehavior = (scrollBehavior as? MiuixGlassScrollBehavior)?.miuixBehavior scrollBehavior = (scrollBehavior as? MiuixGlassScrollBehavior)?.miuixBehavior
) )
} }
@@ -77,7 +105,7 @@ fun GlassMediumFlexibleTopAppBar(
navigationIcon = navigationIcon, navigationIcon = navigationIcon,
actions = actions, actions = actions,
scrollBehavior = (scrollBehavior as? M3GlassScrollBehavior)?.m3Behavior, scrollBehavior = (scrollBehavior as? M3GlassScrollBehavior)?.m3Behavior,
colors = colors colors = transparentColors // 应用透明背景
) )
} else { } else {
TopAppBar( TopAppBar(
@@ -93,11 +121,13 @@ fun GlassMediumFlexibleTopAppBar(
navigationIcon = navigationIcon, navigationIcon = navigationIcon,
actions = actions, actions = actions,
scrollBehavior = (scrollBehavior as? M3GlassScrollBehavior)?.m3Behavior, scrollBehavior = (scrollBehavior as? M3GlassScrollBehavior)?.m3Behavior,
colors = colors colors = transparentColors // 应用透明背景
) )
} }
} }
} }
// 现在的 bottomContent 完美包裹在外层 Column 内,共享渐变和模糊效果!
bottomContent?.invoke(this) bottomContent?.invoke(this)
} }
} }
@@ -178,7 +178,6 @@
<string-array name="composeEngine"> <string-array name="composeEngine">
<item>Material Design</item> <item>Material Design</item>
<item>SaltUI</item>
<item>Miuix</item> <item>Miuix</item>
</string-array> </string-array>
+1 -1
View File
@@ -493,7 +493,7 @@
<string name="share_selected_source">分享选中源</string> <string name="share_selected_source">分享选中源</string>
<string name="scan_qr_code">扫描二维码</string> <string name="scan_qr_code">扫描二维码</string>
<string name="click_on_selected_show_menu">选中时点击可弹出菜单</string> <string name="click_on_selected_show_menu">选中时点击可弹出菜单</string>
<string name="theme">主题</string> <string name="theme">主题模式</string>
<string name="theme_mode">深色模式</string> <string name="theme_mode">深色模式</string>
<string name="theme_mode_desc">选择主题模式</string> <string name="theme_mode_desc">选择主题模式</string>
<string name="join_qq_group">加入 QQ 群</string> <string name="join_qq_group">加入 QQ 群</string>
-1
View File
@@ -105,7 +105,6 @@
<string-array name="composeEngine_value"> <string-array name="composeEngine_value">
<item>material</item> <item>material</item>
<item>salt</item>
<item>miuix</item> <item>miuix</item>
</string-array> </string-array>
-1
View File
@@ -219,7 +219,6 @@
<string-array name="composeEngine"> <string-array name="composeEngine">
<item>Material Design</item> <item>Material Design</item>
<item>SaltUI</item>
<item>Miuix</item> <item>Miuix</item>
</string-array> </string-array>
+1 -1
View File
@@ -1,5 +1,5 @@
VERSION_MAJOR=3 VERSION_MAJOR=3
VERSION_MINOR=26 VERSION_MINOR=26
VERSION_PATCH=10 VERSION_PATCH=11
VERSION_SUFFIX=1 VERSION_SUFFIX=1
# 1 = Pre, 0 = Release # 1 = Pre, 0 = Release