[优化] 优化了发现页中,选择分类页面的性能
This commit is contained in:
1 file changed
+87
-80
@@ -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,104 +181,118 @@ 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)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
Slider(
|
Spacer(modifier = Modifier.width(12.dp))
|
||||||
value = gridColumnCount.toFloat(),
|
|
||||||
onValueChange = {
|
TextCard(
|
||||||
val col = it.toInt().coerceIn(1, 10)
|
text = "$gridColumnCount 列",
|
||||||
viewModel.saveGridCount(col)
|
textStyle = MaterialTheme.typography.titleSmall,
|
||||||
},
|
verticalPadding = 4.dp,
|
||||||
valueRange = 1f..10f,
|
horizontalPadding = 12.dp,
|
||||||
steps = 8,
|
cornerRadius = 12.dp
|
||||||
modifier = Modifier.padding(horizontal = 8.dp)
|
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
Spacer(Modifier.height(20.dp))
|
Slider(
|
||||||
|
value = gridColumnCount.toFloat(),
|
||||||
|
onValueChange = {
|
||||||
|
val col = it.toInt().coerceIn(1, 10)
|
||||||
|
viewModel.saveGridCount(col)
|
||||||
|
},
|
||||||
|
valueRange = 1f..10f,
|
||||||
|
steps = 8,
|
||||||
|
modifier = Modifier.padding(horizontal = 20.dp)
|
||||||
|
)
|
||||||
|
|
||||||
OutlinedButton (
|
Spacer(Modifier.height(24.dp))
|
||||||
onClick = { showGridCountSheet = false },
|
|
||||||
modifier = Modifier.fillMaxWidth()
|
OutlinedButton(
|
||||||
) {
|
onClick = { showGridCountSheet = false },
|
||||||
Text("完成")
|
modifier = Modifier
|
||||||
}
|
.fillMaxWidth()
|
||||||
|
.padding(horizontal = 16.dp)
|
||||||
|
) {
|
||||||
|
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,
|
modifier = Modifier
|
||||||
onDismissRequest = { showKindSheet = false }
|
.heightIn(max = LocalConfiguration.current.screenHeightDp.dp * 0.72f)
|
||||||
) {
|
) {
|
||||||
Column(
|
|
||||||
modifier = Modifier
|
|
||||||
.hazeEffect(state = hazeState, style = HazeMaterials.regular())
|
|
||||||
.fillMaxWidth()
|
|
||||||
.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,
|
||||||
onQueryChange = { kindQuery = it },
|
backgroundColor = MaterialTheme.colorScheme.surfaceContainerHigh,
|
||||||
placeholder = "选择或搜索分类",
|
onQueryChange = { kindQuery = it },
|
||||||
backgroundColor = MaterialTheme.colorScheme.surfaceContainerHigh
|
placeholder = "选择或搜索分类",
|
||||||
)
|
)
|
||||||
|
|
||||||
val filteredKinds = remember(kindQuery, kinds) {
|
val filteredKinds = remember(kindQuery, kinds) {
|
||||||
if (kindQuery.isBlank()) kinds
|
if (kindQuery.isBlank()) kinds
|
||||||
else kinds.filter { kind ->
|
else kinds.filter { kind ->
|
||||||
kind.title.contains(kindQuery, ignoreCase = true) ||
|
kind.title.contains(kindQuery, ignoreCase = true) ||
|
||||||
(kind.url?.contains(kindQuery, ignoreCase = true) == true)
|
(kind.url?.contains(kindQuery, ignoreCase = true) == true)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FlowRow(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(16.dp),
|
|
||||||
maxItemsInEachRow = 3, // 强制每行最多 3 个
|
|
||||||
horizontalArrangement = Arrangement.spacedBy(0.dp) // 因为 Item 内部有 padding,这里设为 0
|
|
||||||
) {
|
|
||||||
filteredKinds.forEach { kind ->
|
|
||||||
KindListItem(
|
|
||||||
kind = kind,
|
|
||||||
currentTitle = selectedTitle ?: title,
|
|
||||||
onClick = {
|
|
||||||
showKindSheet = false
|
|
||||||
viewModel.switchExploreUrl(kind)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LazyVerticalGrid(
|
||||||
|
columns = GridCells.Fixed(3),
|
||||||
|
contentPadding = PaddingValues(16.dp),
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||||
|
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||||
|
modifier = Modifier.weight(1f, fill = false)
|
||||||
|
) {
|
||||||
|
itemsIndexed(
|
||||||
|
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,
|
||||||
|
currentTitle = selectedTitle ?: title,
|
||||||
|
onClick = {
|
||||||
|
showKindSheet = false
|
||||||
|
viewModel.switchExploreUrl(kind)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user