[优化] 优化了发现页中,选择分类页面的性能

This commit is contained in:
HapeLee committed 2026-01-10 03:04:42 +08:00
1 parent 74795d05e8
commit 6d5bf0828e
1 file changed
+51 -44
@@ -14,8 +14,6 @@ import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.FlowRowScope
import androidx.compose.foundation.layout.IntrinsicSize import androidx.compose.foundation.layout.IntrinsicSize
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
@@ -34,12 +32,12 @@ import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.GridItemSpan import androidx.compose.foundation.lazy.grid.GridItemSpan
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items import androidx.compose.foundation.lazy.grid.items
import androidx.compose.foundation.lazy.grid.itemsIndexed
import androidx.compose.foundation.lazy.grid.rememberLazyGridState import androidx.compose.foundation.lazy.grid.rememberLazyGridState
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.automirrored.outlined.FormatListBulleted import androidx.compose.material.icons.automirrored.outlined.FormatListBulleted
@@ -58,7 +56,6 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.MediumFlexibleTopAppBar import androidx.compose.material3.MediumFlexibleTopAppBar
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.OutlinedButton import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
import androidx.compose.material3.SheetValue import androidx.compose.material3.SheetValue
@@ -92,7 +89,6 @@ import dev.chrisbanes.haze.HazeState
import dev.chrisbanes.haze.hazeEffect import dev.chrisbanes.haze.hazeEffect
import dev.chrisbanes.haze.hazeSource import dev.chrisbanes.haze.hazeSource
import dev.chrisbanes.haze.materials.ExperimentalHazeMaterialsApi import dev.chrisbanes.haze.materials.ExperimentalHazeMaterialsApi
import dev.chrisbanes.haze.materials.HazeMaterials
import io.legado.app.data.entities.SearchBook import io.legado.app.data.entities.SearchBook
import io.legado.app.data.entities.rule.ExploreKind import io.legado.app.data.entities.rule.ExploreKind
import io.legado.app.model.BookShelfState import io.legado.app.model.BookShelfState
@@ -100,6 +96,8 @@ import io.legado.app.ui.widget.components.AnimatedTextButton
import io.legado.app.ui.widget.components.AnimatedTextLine import io.legado.app.ui.widget.components.AnimatedTextLine
import io.legado.app.ui.widget.components.Cover import io.legado.app.ui.widget.components.Cover
import io.legado.app.ui.widget.components.SearchBarSection import io.legado.app.ui.widget.components.SearchBarSection
import io.legado.app.ui.widget.components.TextCard
import io.legado.app.ui.widget.components.modalBottomSheet.GlobalModalBottomSheet
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import org.koin.androidx.compose.koinViewModel import org.koin.androidx.compose.koinViewModel
@@ -183,24 +181,35 @@ fun ExploreShowScreen(
skipPartiallyExpanded = true skipPartiallyExpanded = true
) )
ModalBottomSheet( GlobalModalBottomSheet(
sheetState = sheetState, sheetState = sheetState,
dragHandle = null, modifier = Modifier
.padding(16.dp),
onDismissRequest = { showGridCountSheet = false } onDismissRequest = { showGridCountSheet = false }
) { ) {
Column( Row(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.hazeEffect(state = hazeState, style = HazeMaterials.regular()) .padding(bottom = 16.dp),
.padding(16.dp) verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center
) { ) {
Text( Text(
text = "当前:$gridColumnCount 列", text = "布局列数",
style = MaterialTheme.typography.titleLarge, style = MaterialTheme.typography.titleMedium.copy(fontWeight = FontWeight.Bold)
modifier = Modifier.padding(bottom = 12.dp)
) )
Spacer(modifier = Modifier.width(12.dp))
TextCard(
text = "$gridColumnCount 列",
textStyle = MaterialTheme.typography.titleSmall,
verticalPadding = 4.dp,
horizontalPadding = 12.dp,
cornerRadius = 12.dp
)
}
Slider( Slider(
value = gridColumnCount.toFloat(), value = gridColumnCount.toFloat(),
onValueChange = { onValueChange = {
@@ -209,49 +218,44 @@ fun ExploreShowScreen(
}, },
valueRange = 1f..10f, valueRange = 1f..10f,
steps = 8, steps = 8,
modifier = Modifier.padding(horizontal = 8.dp) modifier = Modifier.padding(horizontal = 20.dp)
) )
Spacer(Modifier.height(20.dp)) Spacer(Modifier.height(24.dp))
OutlinedButton( OutlinedButton(
onClick = { showGridCountSheet = false }, onClick = { showGridCountSheet = false },
modifier = Modifier.fillMaxWidth() modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp)
) { ) {
Text("完成") Text("完成")
} }
} }
} }
}
if (showKindSheet) { if (showKindSheet) {
val scrollState = rememberScrollState()
val sheetState = rememberModalBottomSheetState( val sheetState = rememberModalBottomSheetState(
skipPartiallyExpanded = true, skipPartiallyExpanded = true,
confirmValueChange = { newValue -> confirmValueChange = { newValue ->
newValue != SheetValue.PartiallyExpanded newValue != SheetValue.PartiallyExpanded
} }
) )
ModalBottomSheet(
GlobalModalBottomSheet(
onDismissRequest = { showKindSheet = false },
sheetState = sheetState, sheetState = sheetState,
dragHandle = null,
onDismissRequest = { showKindSheet = false }
) {
Column(
modifier = Modifier modifier = Modifier
.hazeEffect(state = hazeState, style = HazeMaterials.regular())
.fillMaxWidth()
.heightIn(max = LocalConfiguration.current.screenHeightDp.dp * 0.72f) .heightIn(max = LocalConfiguration.current.screenHeightDp.dp * 0.72f)
.verticalScroll(scrollState)
) { ) {
var kindQuery by remember { mutableStateOf("") } var kindQuery by remember { mutableStateOf("") }
SearchBarSection( SearchBarSection(
query = kindQuery, query = kindQuery,
backgroundColor = MaterialTheme.colorScheme.surfaceContainerHigh,
onQueryChange = { kindQuery = it }, onQueryChange = { kindQuery = it },
placeholder = "选择或搜索分类", placeholder = "选择或搜索分类",
backgroundColor = MaterialTheme.colorScheme.surfaceContainerHigh
) )
val filteredKinds = remember(kindQuery, kinds) { val filteredKinds = remember(kindQuery, kinds) {
@@ -262,15 +266,23 @@ fun ExploreShowScreen(
} }
} }
FlowRow( LazyVerticalGrid(
modifier = Modifier columns = GridCells.Fixed(3),
.fillMaxWidth() contentPadding = PaddingValues(16.dp),
.padding(16.dp), horizontalArrangement = Arrangement.spacedBy(8.dp),
maxItemsInEachRow = 3, // 强制每行最多 3 个 verticalArrangement = Arrangement.spacedBy(8.dp),
horizontalArrangement = Arrangement.spacedBy(0.dp) // 因为 Item 内部有 padding,这里设为 0 modifier = Modifier.weight(1f, fill = false)
) { ) {
filteredKinds.forEach { kind -> itemsIndexed(
KindListItem( items = filteredKinds,
key = { index, kind -> "${kind.url ?: kind.title}_$index" },
span = { _, kind ->
val isClickable = !kind.url.isNullOrBlank()
if (isClickable) GridItemSpan(1) else GridItemSpan(3)
}
) { _, kind ->
KindGridItem(
modifier = Modifier.animateItem(),
kind = kind, kind = kind,
currentTitle = selectedTitle ?: title, currentTitle = selectedTitle ?: title,
onClick = { onClick = {
@@ -280,7 +292,7 @@ fun ExploreShowScreen(
) )
} }
} }
}
} }
} }
@@ -380,7 +392,7 @@ fun ExploreShowScreen(
} }
@Composable @Composable
fun FlowRowScope.KindListItem( fun KindGridItem(
kind: ExploreKind, kind: ExploreKind,
currentTitle: String?, currentTitle: String?,
onClick: () -> Unit, onClick: () -> Unit,
@@ -403,12 +415,7 @@ fun FlowRowScope.KindListItem(
overflow = TextOverflow.Ellipsis overflow = TextOverflow.Ellipsis
) )
}, },
modifier = modifier modifier = modifier.fillMaxWidth()
.padding(horizontal = 4.dp)
.then(
if (!isClickable) Modifier.fillMaxWidth()
else Modifier.weight(1f)
)
) )
} }