perf: 优化页面性能

This commit is contained in:
Super12138 2025-02-12 16:17:46 +08:00
parent 9c4c6d6b32
commit 563e26af3c
2 changed files with 55 additions and 29 deletions

View file

@ -1,6 +1,10 @@
package cn.super12138.todo.ui.components package cn.super12138.todo.ui.components
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.expandIn
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.shrinkOut
import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.FlowRow import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
@ -16,6 +20,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalView import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
@ -39,29 +44,45 @@ fun FilterChipGroup(
FlowRow(modifier = modifier) { FlowRow(modifier = modifier) {
items.forEachIndexed { index, item -> items.forEachIndexed { index, item ->
FilterChip( FilterChipItem(
selected = items[selectedItemIndex] == items[index], selected = items[selectedItemIndex] == items[index],
text = item,
onClick = { onClick = {
selectedItemIndex = index selectedItemIndex = index
VibrationUtils.performHapticFeedback(view) VibrationUtils.performHapticFeedback(view)
onSelectedChanged(index) onSelectedChanged(index)
}, }
leadingIcon = {
AnimatedVisibility(
visible = items[selectedItemIndex] == items[index]
) {
Icon(
imageVector = Icons.Outlined.Check,
contentDescription = stringResource(R.string.tip_select_this),
modifier = Modifier.size(FilterChipDefaults.IconSize)
)
}
},
label = {
Text(item)
},
modifier = Modifier.padding(end = 10.dp)
) )
} }
} }
}
@Composable
fun FilterChipItem(
selected: Boolean,
text: String,
onClick: () -> Unit,
modifier: Modifier = Modifier
) {
FilterChip(
selected = selected,
onClick = onClick,
leadingIcon = {
AnimatedVisibility(
visible = selected,
enter = expandIn(expandFrom = Alignment.CenterStart) + fadeIn(),
exit = shrinkOut(shrinkTowards = Alignment.CenterStart) + fadeOut()
) {
Icon(
imageVector = Icons.Outlined.Check,
contentDescription = stringResource(R.string.tip_select_this),
modifier = Modifier.size(FilterChipDefaults.IconSize)
)
}
},
label = {
Text(text)
},
modifier = Modifier.padding(end = 10.dp)
)
} }

View file

@ -51,7 +51,7 @@ fun MainPage(
animatedVisibilityScope: AnimatedVisibilityScope, animatedVisibilityScope: AnimatedVisibilityScope,
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {
val toDoList = viewModel.sortedTodos.collectAsState(initial = emptyList()) val toDos = viewModel.sortedTodos.collectAsState(initial = emptyList())
val listState = rememberLazyListState() val listState = rememberLazyListState()
/*val isExpanded by remember { /*val isExpanded by remember {
derivedStateOf { derivedStateOf {
@ -59,20 +59,25 @@ fun MainPage(
} }
}*/ }*/
val selectedTodoIds = viewModel.selectedTodoIds.collectAsState() val selectedTodos = viewModel.selectedTodoIds.collectAsState()
var showDeleteConfirmDialog by rememberSaveable { mutableStateOf(false) } var showDeleteConfirmDialog by rememberSaveable { mutableStateOf(false) }
val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass
val selectedTodoIds by remember {
derivedStateOf { selectedTodos.value }
}
val isSelectedIdsEmpty by remember { val isSelectedIdsEmpty by remember {
derivedStateOf { derivedStateOf {
selectedTodoIds.value.isEmpty() selectedTodoIds.isEmpty()
} }
} }
val toDoList by remember { derivedStateOf { toDos.value } }
val showCompleted = viewModel.showCompletedTodos val showCompleted = viewModel.showCompletedTodos
val filteredTodoList = val filteredTodoList =
if (showCompleted) toDoList.value else toDoList.value.filter { item -> !item.isCompleted } if (showCompleted) toDoList else toDoList.filter { item -> !item.isCompleted }
BackHandler(enabled = !isSelectedIdsEmpty) { BackHandler(enabled = !isSelectedIdsEmpty) {
// 当按下返回键(或进行返回操作)时清空选择 // 当按下返回键(或进行返回操作)时清空选择
@ -82,7 +87,7 @@ fun MainPage(
Scaffold( Scaffold(
topBar = { topBar = {
TodoTopAppBar( TodoTopAppBar(
selectedTodoIds = selectedTodoIds.value, selectedTodoIds = selectedTodoIds,
selectedMode = !isSelectedIdsEmpty, selectedMode = !isSelectedIdsEmpty,
onCancelSelect = { viewModel.clearAllTodoSelection() }, onCancelSelect = { viewModel.clearAllTodoSelection() },
onSelectAll = { viewModel.toggleAllSelected() }, onSelectAll = { viewModel.toggleAllSelected() },
@ -118,8 +123,8 @@ fun MainPage(
if (windowSizeClass.windowWidthSizeClass == WindowWidthSizeClass.COMPACT) { if (windowSizeClass.windowWidthSizeClass == WindowWidthSizeClass.COMPACT) {
Column(modifier = Modifier.padding(innerPadding)) { Column(modifier = Modifier.padding(innerPadding)) {
ProgressFragment( ProgressFragment(
totalTasks = toDoList.value.size, totalTasks = toDoList.size,
completedTasks = toDoList.value.count { it.isCompleted }, completedTasks = toDoList.count { it.isCompleted },
modifier = Modifier modifier = Modifier
.weight(2f) .weight(2f)
.fillMaxSize() .fillMaxSize()
@ -153,7 +158,7 @@ fun MainPage(
viewModel.playConfetti() viewModel.playConfetti()
} }
}, },
selectedTodoIds = selectedTodoIds.value, selectedTodoIds = selectedTodoIds,
sharedTransitionScope = sharedTransitionScope, sharedTransitionScope = sharedTransitionScope,
animatedVisibilityScope = animatedVisibilityScope, animatedVisibilityScope = animatedVisibilityScope,
modifier = Modifier modifier = Modifier
@ -164,8 +169,8 @@ fun MainPage(
} else { } else {
Row(modifier = Modifier.padding(innerPadding)) { Row(modifier = Modifier.padding(innerPadding)) {
ProgressFragment( ProgressFragment(
totalTasks = toDoList.value.size, totalTasks = toDoList.size,
completedTasks = toDoList.value.count { it.isCompleted }, completedTasks = toDoList.count { it.isCompleted },
modifier = Modifier modifier = Modifier
.weight(2f) .weight(2f)
.fillMaxSize() .fillMaxSize()
@ -198,7 +203,7 @@ fun MainPage(
viewModel.playConfetti() viewModel.playConfetti()
} }
}, },
selectedTodoIds = selectedTodoIds.value, selectedTodoIds = selectedTodoIds,
sharedTransitionScope = sharedTransitionScope, sharedTransitionScope = sharedTransitionScope,
animatedVisibilityScope = animatedVisibilityScope, animatedVisibilityScope = animatedVisibilityScope,
modifier = Modifier modifier = Modifier
@ -212,7 +217,7 @@ fun MainPage(
WarningDialog( WarningDialog(
visible = showDeleteConfirmDialog, visible = showDeleteConfirmDialog,
icon = Icons.Outlined.Delete, icon = Icons.Outlined.Delete,
description = stringResource(R.string.tip_delete_task, selectedTodoIds.value.size), description = stringResource(R.string.tip_delete_task, selectedTodoIds.size),
onConfirm = { viewModel.deleteSelectedTodo() }, onConfirm = { viewModel.deleteSelectedTodo() },
onDismiss = { showDeleteConfirmDialog = false } onDismiss = { showDeleteConfirmDialog = false }
) )