refactor: 组件化顶部应用栏

This commit is contained in:
Super12138 2025-01-15 16:55:54 +08:00
parent 366f19ca06
commit 0f27eab03b
2 changed files with 105 additions and 60 deletions

View file

@ -43,6 +43,7 @@ import androidx.window.core.layout.WindowWidthSizeClass
import cn.super12138.todo.R
import cn.super12138.todo.logic.database.TodoEntity
import cn.super12138.todo.ui.pages.main.components.TodoFAB
import cn.super12138.todo.ui.pages.main.components.TodoTopAppBar
import cn.super12138.todo.ui.viewmodels.MainViewModel
import kotlinx.coroutines.launch
@ -71,10 +72,6 @@ fun MainPage(viewModel: MainViewModel, modifier: Modifier = Modifier) {
}
}
val animatedTopAppBarColors by animateColorAsState(
targetValue = if (isSelectedIdsEmpty) MaterialTheme.colorScheme.surface else MaterialTheme.colorScheme.surfaceContainerHighest
)
BackHandler(enabled = !isSelectedIdsEmpty) {
// 当按下返回键(或进行返回操作)时清空选择
viewModel.clearAllTodoSelection()
@ -82,62 +79,13 @@ fun MainPage(viewModel: MainViewModel, modifier: Modifier = Modifier) {
Scaffold(
topBar = {
TopAppBar(
navigationIcon = {
AnimatedVisibility(!isSelectedIdsEmpty) {
IconButton(onClick = { viewModel.clearAllTodoSelection() }) {
Icon(
imageVector = Icons.Outlined.Close,
contentDescription = stringResource(R.string.tip_clear_selected_items)
)
}
}
},
title = {
Text(
text = if (isSelectedIdsEmpty) {
stringResource(R.string.app_name)
} else {
stringResource(
R.string.title_selected_count,
selectedTodoIds.value.size
)
}
)
},
actions = {
AnimatedContent(isSelectedIdsEmpty) { isEmpty ->
if (isEmpty) {
IconButton(
onClick = {}
) {
Icon(
imageVector = Icons.Outlined.Settings,
contentDescription = stringResource(R.string.page_settings)
)
}
} else {
Row {
IconButton(onClick = { viewModel.toggleAllSelected() }) {
Icon(
imageVector = Icons.Outlined.SelectAll,
contentDescription = stringResource(R.string.tip_select_all)
)
}
IconButton(onClick = { viewModel.deleteSelectedTodo() }) {
Icon(
imageVector = Icons.Outlined.Delete,
contentDescription = stringResource(R.string.action_delete)
)
}
}
}
}
},
colors = TopAppBarDefaults.largeTopAppBarColors().copy(
containerColor = animatedTopAppBarColors
)
TodoTopAppBar(
selectedTodoIds = selectedTodoIds.value,
selectedMode = !isSelectedIdsEmpty,
onCancelSelect = { viewModel.clearAllTodoSelection() },
onSelectAll = { viewModel.toggleAllSelected() },
onDeleteSelectedTodo = { viewModel.deleteSelectedTodo() },
toSettingsPage = {}
)
},
floatingActionButton = {

View file

@ -0,0 +1,97 @@
package cn.super12138.todo.ui.pages.main.components
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateColorAsState
import androidx.compose.foundation.layout.Row
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Close
import androidx.compose.material.icons.outlined.Delete
import androidx.compose.material.icons.outlined.SelectAll
import androidx.compose.material.icons.outlined.Settings
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import cn.super12138.todo.R
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TodoTopAppBar(
selectedTodoIds: List<Int>,
selectedMode: Boolean,
onCancelSelect: () -> Unit,
onSelectAll: () -> Unit,
onDeleteSelectedTodo: () -> Unit,
toSettingsPage: () -> Unit,
modifier: Modifier = Modifier
) {
val animatedTopAppBarColors by animateColorAsState(
targetValue = if (selectedMode) MaterialTheme.colorScheme.surfaceContainerHighest else MaterialTheme.colorScheme.surface
)
TopAppBar(
navigationIcon = {
AnimatedVisibility(selectedMode) {
IconButton(onClick = onCancelSelect) {
Icon(
imageVector = Icons.Outlined.Close,
contentDescription = stringResource(R.string.tip_clear_selected_items)
)
}
}
},
title = {
Text(
text = if (!selectedMode) {
stringResource(R.string.app_name)
} else {
stringResource(
R.string.title_selected_count,
selectedTodoIds.size
)
}
)
},
actions = {
AnimatedContent(selectedMode) { inSelectedMode ->
if (!inSelectedMode) {
IconButton(
onClick = toSettingsPage
) {
Icon(
imageVector = Icons.Outlined.Settings,
contentDescription = stringResource(R.string.page_settings)
)
}
} else {
Row {
IconButton(onClick = onSelectAll) {
Icon(
imageVector = Icons.Outlined.SelectAll,
contentDescription = stringResource(R.string.tip_select_all)
)
}
IconButton(onClick = onDeleteSelectedTodo) {
Icon(
imageVector = Icons.Outlined.Delete,
contentDescription = stringResource(R.string.action_delete)
)
}
}
}
}
},
colors = TopAppBarDefaults.largeTopAppBarColors().copy(
containerColor = animatedTopAppBarColors
)
)
}