feat: 将待办 BottomSheet 提取为单独页面
This commit is contained in:
parent
9f3fd5f7ec
commit
ca08c21ca5
6 changed files with 48 additions and 66 deletions
|
|
@ -6,6 +6,7 @@ import androidx.navigation.NavHostController
|
|||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import cn.super12138.todo.ui.pages.editor.TodoEditorPage
|
||||
import cn.super12138.todo.ui.pages.main.MainPage
|
||||
import cn.super12138.todo.ui.pages.settings.SettingsAbout
|
||||
import cn.super12138.todo.ui.pages.settings.SettingsAboutLicence
|
||||
|
|
@ -51,10 +52,32 @@ fun TodoNavigation(
|
|||
composable(TodoScreen.Main.name) {
|
||||
MainPage(
|
||||
viewModel = viewModel,
|
||||
toTodoEditPage = { navController.navigate(TodoScreen.TodoEditor.name) },
|
||||
toSettingsPage = { navController.navigate(TodoScreen.SettingsMain.name) }
|
||||
)
|
||||
}
|
||||
|
||||
composable(TodoScreen.TodoEditor.name) {
|
||||
TodoEditorPage(
|
||||
toDo = viewModel.selectedEditTodo,
|
||||
onSave = {
|
||||
viewModel.addTodo(it)
|
||||
navController.navigateUp()
|
||||
},
|
||||
onDelete = {
|
||||
if (viewModel.selectedEditTodo !== null) {
|
||||
viewModel.deleteTodo(viewModel.selectedEditTodo!!)
|
||||
viewModel.setEditTodoItem(null)
|
||||
}
|
||||
navController.navigateUp()
|
||||
},
|
||||
onNavigateUp = {
|
||||
viewModel.setEditTodoItem(null)
|
||||
navController.navigateUp()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
composable(TodoScreen.SettingsMain.name) {
|
||||
SettingsMain(
|
||||
onNavigateUp = { navController.navigateUp() },
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package cn.super12138.todo.ui.navigation
|
|||
|
||||
enum class TodoScreen {
|
||||
Main,
|
||||
TodoEditor,
|
||||
SettingsMain,
|
||||
SettingsAbout,
|
||||
SettingsAboutLicence
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
package cn.super12138.todo.ui.pages.main
|
||||
package cn.super12138.todo.ui.pages.editor
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
|
|
@ -14,11 +15,9 @@ import androidx.compose.material3.ButtonColors
|
|||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.FilledTonalButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.ModalBottomSheet
|
||||
import androidx.compose.material3.OutlinedButton
|
||||
import androidx.compose.material3.SheetState
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextField
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
|
|
@ -26,7 +25,6 @@ import androidx.compose.runtime.mutableStateOf
|
|||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
|
|
@ -36,38 +34,32 @@ import cn.super12138.todo.logic.database.TodoEntity
|
|||
import cn.super12138.todo.logic.model.Subjects
|
||||
import cn.super12138.todo.ui.TodoDefaults
|
||||
import cn.super12138.todo.ui.components.FilterChipGroup
|
||||
import cn.super12138.todo.ui.components.LargeTopAppBarScaffold
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun TodoBottomSheet(
|
||||
sheetState: SheetState,
|
||||
onDismissRequest: () -> Unit,
|
||||
fun TodoEditorPage(
|
||||
toDo: TodoEntity? = null,
|
||||
onSave: (TodoEntity) -> Unit,
|
||||
onClose: () -> Unit,
|
||||
onDelete: () -> Unit,
|
||||
onNavigateUp: () -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
|
||||
ModalBottomSheet(
|
||||
sheetState = sheetState,
|
||||
onDismissRequest = onDismissRequest,
|
||||
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
|
||||
LargeTopAppBarScaffold(
|
||||
title = stringResource(if (toDo != null) R.string.title_edit_task else R.string.action_add_task),
|
||||
scrollBehavior = scrollBehavior,
|
||||
onBack = onNavigateUp,
|
||||
modifier = modifier
|
||||
) {
|
||||
) { innerPadding ->
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = Modifier
|
||||
.padding(innerPadding)
|
||||
.padding(horizontal = TodoDefaults.screenPadding)
|
||||
.fillMaxSize()
|
||||
.verticalScroll(rememberScrollState())
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(if (toDo != null) R.string.title_edit_task else R.string.action_add_task),
|
||||
style = MaterialTheme.typography.headlineMedium
|
||||
)
|
||||
|
||||
Spacer(Modifier.size(20.dp))
|
||||
|
||||
var text by rememberSaveable { mutableStateOf(toDo?.content ?: "") }
|
||||
var isError by rememberSaveable { mutableStateOf(false) }
|
||||
TextField(
|
||||
|
|
@ -91,6 +83,10 @@ fun TodoBottomSheet(
|
|||
}
|
||||
}
|
||||
var selectedItemIndex by rememberSaveable { mutableIntStateOf(toDo?.subject ?: 0) }
|
||||
Text(
|
||||
text = stringResource(R.string.label_subject),
|
||||
style = MaterialTheme.typography.titleMedium
|
||||
)
|
||||
FilterChipGroup(
|
||||
items = subjects,
|
||||
defaultSelectedItemIndex = toDo?.subject ?: 0,
|
||||
|
|
@ -102,15 +98,12 @@ fun TodoBottomSheet(
|
|||
|
||||
Spacer(Modifier.size(20.dp))
|
||||
|
||||
// 操作按钮
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(10.dp)) {
|
||||
OutlinedButton(onClick = onClose) {
|
||||
Text(stringResource(R.string.action_cancel))
|
||||
}
|
||||
if (toDo !== null) {
|
||||
FilledTonalButton(
|
||||
onClick = {
|
||||
onDelete()
|
||||
onClose()
|
||||
},
|
||||
colors = ButtonColors(
|
||||
containerColor = MaterialTheme.colorScheme.errorContainer,
|
||||
|
|
@ -139,13 +132,11 @@ fun TodoBottomSheet(
|
|||
id = toDo?.id ?: 0
|
||||
)
|
||||
)
|
||||
onClose()
|
||||
}
|
||||
) {
|
||||
Text(stringResource(R.string.action_save))
|
||||
}
|
||||
}
|
||||
Spacer(Modifier.size(30.dp))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -15,17 +15,14 @@ import androidx.compose.foundation.layout.ime
|
|||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.safeContent
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
|
||||
import androidx.compose.material3.rememberModalBottomSheetState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
|
|
@ -35,12 +32,11 @@ import cn.super12138.todo.ui.pages.main.components.TodoDeleteConfirmDialog
|
|||
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
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun MainPage(
|
||||
viewModel: MainViewModel,
|
||||
toTodoEditPage: () -> Unit,
|
||||
toSettingsPage: () -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
|
|
@ -52,12 +48,8 @@ fun MainPage(
|
|||
}
|
||||
}
|
||||
|
||||
val selectedEditTodoItem = viewModel.selectedEditTodo
|
||||
val selectedTodoIds = viewModel.selectedTodoIds.collectAsState()
|
||||
var showBottomSheet by rememberSaveable { mutableStateOf(false) }
|
||||
var showDeleteConfirmDialog by rememberSaveable { mutableStateOf(false) }
|
||||
val bottomSheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass
|
||||
|
||||
|
|
@ -95,7 +87,7 @@ fun MainPage(
|
|||
) {
|
||||
TodoFAB(
|
||||
expanded = isExpanded,
|
||||
onClick = { showBottomSheet = true }
|
||||
onClick = toTodoEditPage
|
||||
)
|
||||
}
|
||||
},
|
||||
|
|
@ -117,8 +109,8 @@ fun MainPage(
|
|||
list = filteredTodoList,
|
||||
onItemClick = { item ->
|
||||
if (isSelectedIdsEmpty) {
|
||||
showBottomSheet = true
|
||||
viewModel.setEditTodoItem(item)
|
||||
toTodoEditPage()
|
||||
} else {
|
||||
viewModel.toggleTodoSelection(item)
|
||||
}
|
||||
|
|
@ -159,7 +151,6 @@ fun MainPage(
|
|||
list = filteredTodoList,
|
||||
onItemClick = { item ->
|
||||
if (isSelectedIdsEmpty) {
|
||||
showBottomSheet = true
|
||||
viewModel.setEditTodoItem(item)
|
||||
} else {
|
||||
viewModel.toggleTodoSelection(item)
|
||||
|
|
@ -189,32 +180,6 @@ fun MainPage(
|
|||
}
|
||||
}
|
||||
}
|
||||
if (showBottomSheet) {
|
||||
TodoBottomSheet(
|
||||
sheetState = bottomSheetState,
|
||||
onDismissRequest = {
|
||||
showBottomSheet = false
|
||||
viewModel.setEditTodoItem(null)
|
||||
},
|
||||
toDo = selectedEditTodoItem,
|
||||
onSave = { toDo ->
|
||||
viewModel.addTodo(toDo)
|
||||
},
|
||||
onClose = {
|
||||
viewModel.setEditTodoItem(null)
|
||||
scope
|
||||
.launch { bottomSheetState.hide() }
|
||||
.invokeOnCompletion {
|
||||
if (!bottomSheetState.isVisible) {
|
||||
showBottomSheet = false
|
||||
}
|
||||
}
|
||||
},
|
||||
onDelete = {
|
||||
if (selectedEditTodoItem !== null) viewModel.deleteTodo(selectedEditTodoItem)
|
||||
}
|
||||
)
|
||||
}
|
||||
if (showDeleteConfirmDialog) {
|
||||
TodoDeleteConfirmDialog(
|
||||
onConfirm = {
|
||||
|
|
|
|||
|
|
@ -39,4 +39,5 @@
|
|||
<string name="pref_developer">开发者</string>
|
||||
<string name="pref_licence">开放源代码许可</string>
|
||||
<string name="pref_licence_desc">查看应用使用的开源库及其许可</string>
|
||||
<string name="label_subject">学科</string>
|
||||
</resources>
|
||||
|
|
@ -40,4 +40,5 @@
|
|||
<string name="pref_developer">Developer</string>
|
||||
<string name="pref_licence">Open Source Licences</string>
|
||||
<string name="pref_licence_desc">Check the open source libraries used by the application and their licences.</string>
|
||||
<string name="label_subject">Subject</string>
|
||||
</resources>
|
||||
Loading…
Reference in a new issue