feat: 使用 Navigation3 导航 & 对 FAB 动画进行 MD3E 适配
This commit is contained in:
parent
66e9ab82d2
commit
0fb4192493
11 changed files with 172 additions and 164 deletions
|
|
@ -100,7 +100,6 @@ dependencies {
|
||||||
implementation(libs.androidx.activity.compose)
|
implementation(libs.androidx.activity.compose)
|
||||||
implementation(platform(libs.androidx.compose.bom))
|
implementation(platform(libs.androidx.compose.bom))
|
||||||
implementation(libs.androidx.animation)
|
implementation(libs.androidx.animation)
|
||||||
implementation(libs.androidx.navigation)
|
|
||||||
implementation(libs.androidx.material3.adaptive)
|
implementation(libs.androidx.material3.adaptive)
|
||||||
implementation(libs.androidx.ui)
|
implementation(libs.androidx.ui)
|
||||||
implementation(libs.androidx.ui.android)
|
implementation(libs.androidx.ui.android)
|
||||||
|
|
@ -109,6 +108,8 @@ dependencies {
|
||||||
implementation(libs.androidx.material3)
|
implementation(libs.androidx.material3)
|
||||||
implementation(libs.androidx.material.icon.core)
|
implementation(libs.androidx.material.icon.core)
|
||||||
implementation(libs.androidx.material.icon.extended)
|
implementation(libs.androidx.material.icon.extended)
|
||||||
|
implementation(libs.androidx.navigation3.runtime)
|
||||||
|
implementation(libs.androidx.navigation3.ui)
|
||||||
// About Libraries
|
// About Libraries
|
||||||
implementation(libs.aboutlibraries.core)
|
implementation(libs.aboutlibraries.core)
|
||||||
implementation(libs.aboutlibraries.compose)
|
implementation(libs.aboutlibraries.compose)
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,9 @@ import androidx.room.ColumnInfo
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
import cn.super12138.todo.constants.Constants
|
import cn.super12138.todo.constants.Constants
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
@Entity(tableName = Constants.DB_TABLE_NAME)
|
@Entity(tableName = Constants.DB_TABLE_NAME)
|
||||||
data class TodoEntity(
|
data class TodoEntity(
|
||||||
@ColumnInfo(name = "content") val content: String,
|
@ColumnInfo(name = "content") val content: String,
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,9 @@ import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
import androidx.compose.ui.platform.LocalView
|
import androidx.compose.ui.platform.LocalView
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.compose.ui.window.DialogProperties
|
import androidx.compose.ui.window.DialogProperties
|
||||||
import cn.super12138.todo.R
|
import cn.super12138.todo.R
|
||||||
import cn.super12138.todo.utils.VibrationUtils
|
import cn.super12138.todo.utils.VibrationUtils
|
||||||
import com.kyant.capsule.ContinuousRoundedRectangle
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ConfirmDialog(
|
fun ConfirmDialog(
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,11 @@ import androidx.compose.animation.ExperimentalSharedTransitionApi
|
||||||
import androidx.compose.animation.SharedTransitionLayout
|
import androidx.compose.animation.SharedTransitionLayout
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation3.runtime.NavBackStack
|
||||||
import androidx.navigation.compose.NavHost
|
import androidx.navigation3.runtime.NavKey
|
||||||
import androidx.navigation.compose.composable
|
import androidx.navigation3.runtime.entryProvider
|
||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation3.runtime.rememberNavBackStack
|
||||||
|
import androidx.navigation3.ui.NavDisplay
|
||||||
import cn.super12138.todo.ui.pages.editor.TodoEditorPage
|
import cn.super12138.todo.ui.pages.editor.TodoEditorPage
|
||||||
import cn.super12138.todo.ui.pages.main.MainPage
|
import cn.super12138.todo.ui.pages.main.MainPage
|
||||||
import cn.super12138.todo.ui.pages.settings.SettingsAbout
|
import cn.super12138.todo.ui.pages.settings.SettingsAbout
|
||||||
|
|
@ -19,8 +20,7 @@ import cn.super12138.todo.ui.pages.settings.SettingsDeveloperOptions
|
||||||
import cn.super12138.todo.ui.pages.settings.SettingsDeveloperOptionsPadding
|
import cn.super12138.todo.ui.pages.settings.SettingsDeveloperOptionsPadding
|
||||||
import cn.super12138.todo.ui.pages.settings.SettingsInterface
|
import cn.super12138.todo.ui.pages.settings.SettingsInterface
|
||||||
import cn.super12138.todo.ui.pages.settings.SettingsMain
|
import cn.super12138.todo.ui.pages.settings.SettingsMain
|
||||||
import cn.super12138.todo.ui.theme.materialSharedAxisXIn
|
import cn.super12138.todo.ui.theme.materialSharedAxisX
|
||||||
import cn.super12138.todo.ui.theme.materialSharedAxisXOut
|
|
||||||
import cn.super12138.todo.ui.viewmodels.MainViewModel
|
import cn.super12138.todo.ui.viewmodels.MainViewModel
|
||||||
|
|
||||||
private const val INITIAL_OFFSET_FACTOR = 0.10f
|
private const val INITIAL_OFFSET_FACTOR = 0.10f
|
||||||
|
|
@ -29,126 +29,117 @@ private const val INITIAL_OFFSET_FACTOR = 0.10f
|
||||||
@Composable
|
@Composable
|
||||||
fun TodoNavigation(
|
fun TodoNavigation(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
navController: NavHostController = rememberNavController(),
|
backStack: NavBackStack<NavKey> = rememberNavBackStack(TodoScreen.Main),
|
||||||
startDestination: String = TodoScreen.Main.name,
|
|
||||||
viewModel: MainViewModel
|
viewModel: MainViewModel
|
||||||
) {
|
) {
|
||||||
|
fun onBack() {
|
||||||
|
backStack.removeAt(backStack.lastIndex)
|
||||||
|
}
|
||||||
|
|
||||||
SharedTransitionLayout {
|
SharedTransitionLayout {
|
||||||
NavHost(
|
NavDisplay(
|
||||||
navController = navController,
|
backStack = backStack,
|
||||||
startDestination = startDestination,
|
onBack = ::onBack,
|
||||||
enterTransition = {
|
transitionSpec = {
|
||||||
materialSharedAxisXIn(
|
materialSharedAxisX(
|
||||||
initialOffsetX = { (it * INITIAL_OFFSET_FACTOR).toInt() }
|
initialOffsetX = { (it * INITIAL_OFFSET_FACTOR).toInt() },
|
||||||
)
|
targetOffsetX = { -(it * INITIAL_OFFSET_FACTOR).toInt() })
|
||||||
},
|
},
|
||||||
exitTransition = {
|
popTransitionSpec = {
|
||||||
materialSharedAxisXOut(
|
materialSharedAxisX(
|
||||||
targetOffsetX = { -(it * INITIAL_OFFSET_FACTOR).toInt() }
|
initialOffsetX = { -(it * INITIAL_OFFSET_FACTOR).toInt() },
|
||||||
)
|
targetOffsetX = { (it * INITIAL_OFFSET_FACTOR).toInt() })
|
||||||
},
|
},
|
||||||
popEnterTransition = {
|
|
||||||
materialSharedAxisXIn(
|
entryProvider = entryProvider {
|
||||||
initialOffsetX = { -(it * INITIAL_OFFSET_FACTOR).toInt() }
|
entry<TodoScreen.Main> {
|
||||||
)
|
MainPage(
|
||||||
|
viewModel = viewModel,
|
||||||
|
toTodoEditPage = { backStack.add(TodoScreen.Editor(it)) },
|
||||||
|
toSettingsPage = { backStack.add(TodoScreen.SettingsMain) },
|
||||||
|
sharedTransitionScope = this@SharedTransitionLayout
|
||||||
|
)
|
||||||
|
}
|
||||||
|
entry<TodoScreen.Editor> { editorArgs ->
|
||||||
|
TodoEditorPage(
|
||||||
|
toDo = editorArgs.toDo,
|
||||||
|
onSave = {
|
||||||
|
viewModel.addTodo(it)
|
||||||
|
// 如果原来的待办状态为未完成并且修改后状态为完成
|
||||||
|
if (editorArgs.toDo?.isCompleted != true && it.isCompleted) {
|
||||||
|
viewModel.playConfetti()
|
||||||
|
}
|
||||||
|
onBack()
|
||||||
|
},
|
||||||
|
onDelete = {
|
||||||
|
if (editorArgs.toDo !== null) {
|
||||||
|
viewModel.deleteTodo(editorArgs.toDo)
|
||||||
|
}
|
||||||
|
onBack()
|
||||||
|
},
|
||||||
|
onNavigateUp = ::onBack,
|
||||||
|
sharedTransitionScope = this@SharedTransitionLayout
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
entry<TodoScreen.SettingsMain> {
|
||||||
|
SettingsMain(
|
||||||
|
toAppearancePage = { backStack.add(TodoScreen.SettingsAppearance) },
|
||||||
|
toAboutPage = { backStack.add(TodoScreen.SettingsAbout) },
|
||||||
|
toInterfacePage = { backStack.add(TodoScreen.SettingsInterface) },
|
||||||
|
toDataPage = { backStack.add(TodoScreen.SettingsData) },
|
||||||
|
onNavigateUp = ::onBack,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
entry<TodoScreen.SettingsAppearance> {
|
||||||
|
SettingsAppearance(onNavigateUp = ::onBack)
|
||||||
|
}
|
||||||
|
|
||||||
|
entry<TodoScreen.SettingsInterface> {
|
||||||
|
SettingsInterface(onNavigateUp = ::onBack)
|
||||||
|
}
|
||||||
|
|
||||||
|
entry<TodoScreen.SettingsData> {
|
||||||
|
SettingsData(
|
||||||
|
viewModel = viewModel,
|
||||||
|
toCategoryManager = { backStack.add(TodoScreen.SettingsDataCategory) },
|
||||||
|
onNavigateUp = ::onBack
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
entry<TodoScreen.SettingsDataCategory> {
|
||||||
|
SettingsDataCategory(onNavigateUp = ::onBack)
|
||||||
|
}
|
||||||
|
|
||||||
|
entry<TodoScreen.SettingsAbout> {
|
||||||
|
SettingsAbout(
|
||||||
|
//toSpecialPage = { backStack.add(TodoScreen.SettingsAboutSpecial) },
|
||||||
|
toLicencePage = { backStack.add(TodoScreen.SettingsAboutLicence) },
|
||||||
|
toDevPage = { backStack.add(TodoScreen.SettingsDev) },
|
||||||
|
onNavigateUp = ::onBack,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*entry<TodoScreen.SettingsAboutSpecial> {
|
||||||
|
SettingsAboutSpecial(viewModel = viewModel)
|
||||||
|
}*/
|
||||||
|
|
||||||
|
entry<TodoScreen.SettingsAboutLicence> {
|
||||||
|
SettingsAboutLicence(onNavigateUp = ::onBack)
|
||||||
|
}
|
||||||
|
|
||||||
|
entry<TodoScreen.SettingsDev> {
|
||||||
|
SettingsDeveloperOptions(
|
||||||
|
toPaddingPage = { backStack.add(TodoScreen.SettingsDevPadding) },
|
||||||
|
onNavigateUp = ::onBack
|
||||||
|
)
|
||||||
|
}
|
||||||
|
entry<TodoScreen.SettingsDevPadding> {
|
||||||
|
SettingsDeveloperOptionsPadding(onNavigateUp = ::onBack)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
popExitTransition = {
|
modifier = modifier,
|
||||||
materialSharedAxisXOut(
|
)
|
||||||
targetOffsetX = { (it * INITIAL_OFFSET_FACTOR).toInt() }
|
|
||||||
)
|
|
||||||
},
|
|
||||||
modifier = modifier
|
|
||||||
) {
|
|
||||||
composable(TodoScreen.Main.name) {
|
|
||||||
MainPage(
|
|
||||||
viewModel = viewModel,
|
|
||||||
toTodoEditPage = { navController.navigate(TodoScreen.TodoEditor.name) },
|
|
||||||
toSettingsPage = { navController.navigate(TodoScreen.SettingsMain.name) },
|
|
||||||
sharedTransitionScope = this@SharedTransitionLayout,
|
|
||||||
animatedVisibilityScope = this@composable
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
composable(TodoScreen.TodoEditor.name) {
|
|
||||||
TodoEditorPage(
|
|
||||||
toDo = viewModel.selectedEditTodo,
|
|
||||||
onSave = {
|
|
||||||
viewModel.addTodo(it)
|
|
||||||
// 如果原来的待办状态为未完成并且修改后状态为完成
|
|
||||||
if (viewModel.selectedEditTodo?.isCompleted != true && it.isCompleted) {
|
|
||||||
viewModel.playConfetti()
|
|
||||||
}
|
|
||||||
navController.navigateUp()
|
|
||||||
},
|
|
||||||
onDelete = {
|
|
||||||
if (viewModel.selectedEditTodo !== null) {
|
|
||||||
viewModel.deleteTodo(viewModel.selectedEditTodo!!)
|
|
||||||
viewModel.setEditTodoItem(null)
|
|
||||||
}
|
|
||||||
navController.navigateUp()
|
|
||||||
},
|
|
||||||
onNavigateUp = { navController.navigateUp() },
|
|
||||||
sharedTransitionScope = this@SharedTransitionLayout,
|
|
||||||
animatedVisibilityScope = this@composable
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
composable(TodoScreen.SettingsMain.name) {
|
|
||||||
SettingsMain(
|
|
||||||
toAppearancePage = { navController.navigate(TodoScreen.SettingsAppearance.name) },
|
|
||||||
toAboutPage = { navController.navigate(TodoScreen.SettingsAbout.name) },
|
|
||||||
toInterfacePage = { navController.navigate(TodoScreen.SettingsInterface.name) },
|
|
||||||
toDataPage = { navController.navigate(TodoScreen.SettingsData.name) },
|
|
||||||
onNavigateUp = { navController.navigateUp() },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
composable(TodoScreen.SettingsAppearance.name) {
|
|
||||||
SettingsAppearance(onNavigateUp = { navController.navigateUp() })
|
|
||||||
}
|
|
||||||
|
|
||||||
composable(TodoScreen.SettingsInterface.name) {
|
|
||||||
SettingsInterface(onNavigateUp = { navController.navigateUp() })
|
|
||||||
}
|
|
||||||
|
|
||||||
composable(TodoScreen.SettingsData.name) {
|
|
||||||
SettingsData(
|
|
||||||
viewModel = viewModel,
|
|
||||||
toCategoryManager = { navController.navigate(TodoScreen.SettingsDataCategory.name) },
|
|
||||||
onNavigateUp = { navController.navigateUp() }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
composable(TodoScreen.SettingsDataCategory.name) {
|
|
||||||
SettingsDataCategory(onNavigateUp = { navController.navigateUp() })
|
|
||||||
}
|
|
||||||
|
|
||||||
composable(TodoScreen.SettingsAbout.name) {
|
|
||||||
SettingsAbout(
|
|
||||||
//toSpecialPage = { navController.navigate(TodoScreen.SettingsAboutSpecial.name) },
|
|
||||||
toLicencePage = { navController.navigate(TodoScreen.SettingsAboutLicence.name) },
|
|
||||||
toDevPage = { navController.navigate(TodoScreen.SettingsDev.name) },
|
|
||||||
onNavigateUp = { navController.navigateUp() },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/*composable(TodoScreen.SettingsAboutSpecial.name) {
|
|
||||||
SettingsAboutSpecial(viewModel = viewModel)
|
|
||||||
}*/
|
|
||||||
|
|
||||||
composable(TodoScreen.SettingsAboutLicence.name) {
|
|
||||||
SettingsAboutLicence(onNavigateUp = { navController.navigateUp() })
|
|
||||||
}
|
|
||||||
|
|
||||||
composable(TodoScreen.SettingsDev.name) {
|
|
||||||
SettingsDeveloperOptions(
|
|
||||||
toPaddingPage = { navController.navigate(TodoScreen.SettingsDevPadding.name) },
|
|
||||||
onNavigateUp = { navController.navigateUp() }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
composable(TodoScreen.SettingsDevPadding.name) {
|
|
||||||
SettingsDeveloperOptionsPadding(onNavigateUp = { navController.navigateUp() })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,17 +1,44 @@
|
||||||
package cn.super12138.todo.ui.navigation
|
package cn.super12138.todo.ui.navigation
|
||||||
|
|
||||||
enum class TodoScreen {
|
import androidx.navigation3.runtime.NavKey
|
||||||
Main,
|
import cn.super12138.todo.logic.database.TodoEntity
|
||||||
TodoEditor,
|
import kotlinx.serialization.Serializable
|
||||||
SettingsMain,
|
|
||||||
SettingsAppearance,
|
|
||||||
SettingsInterface,
|
|
||||||
SettingsData,
|
|
||||||
SettingsDataCategory,
|
|
||||||
SettingsAbout,
|
|
||||||
|
|
||||||
//SettingsAboutSpecial,
|
@Serializable
|
||||||
SettingsAboutLicence,
|
sealed class TodoScreen : NavKey {
|
||||||
SettingsDev,
|
@Serializable
|
||||||
SettingsDevPadding
|
data object Main : TodoScreen()
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class Editor(val toDo: TodoEntity?) : TodoScreen()
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data object SettingsMain : TodoScreen()
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data object SettingsAppearance : TodoScreen()
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data object SettingsInterface : TodoScreen()
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data object SettingsData : TodoScreen()
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data object SettingsDataCategory : TodoScreen()
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data object SettingsAbout : TodoScreen()
|
||||||
|
|
||||||
|
// @Serializable
|
||||||
|
// data object SettingsAboutSpecial : TodoScreen()
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data object SettingsAboutLicence : TodoScreen()
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data object SettingsDev : TodoScreen()
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data object SettingsDevPadding : TodoScreen()
|
||||||
}
|
}
|
||||||
|
|
@ -2,7 +2,6 @@ package cn.super12138.todo.ui.pages.editor
|
||||||
|
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.animation.AnimatedVisibilityScope
|
|
||||||
import androidx.compose.animation.ExperimentalSharedTransitionApi
|
import androidx.compose.animation.ExperimentalSharedTransitionApi
|
||||||
import androidx.compose.animation.SharedTransitionScope
|
import androidx.compose.animation.SharedTransitionScope
|
||||||
import androidx.compose.animation.expandVertically
|
import androidx.compose.animation.expandVertically
|
||||||
|
|
@ -43,6 +42,7 @@ 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
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.navigation3.ui.LocalNavAnimatedContentScope
|
||||||
import cn.super12138.todo.R
|
import cn.super12138.todo.R
|
||||||
import cn.super12138.todo.constants.Constants
|
import cn.super12138.todo.constants.Constants
|
||||||
import cn.super12138.todo.logic.database.TodoEntity
|
import cn.super12138.todo.logic.database.TodoEntity
|
||||||
|
|
@ -69,11 +69,11 @@ fun TodoEditorPage(
|
||||||
onSave: (TodoEntity) -> Unit,
|
onSave: (TodoEntity) -> Unit,
|
||||||
onDelete: () -> Unit,
|
onDelete: () -> Unit,
|
||||||
onNavigateUp: () -> Unit,
|
onNavigateUp: () -> Unit,
|
||||||
sharedTransitionScope: SharedTransitionScope,
|
sharedTransitionScope: SharedTransitionScope
|
||||||
animatedVisibilityScope: AnimatedVisibilityScope
|
|
||||||
) {
|
) {
|
||||||
// TODO: 本页及其相关组件重组性能检查优化
|
// TODO: 本页及其相关组件重组性能检查优化
|
||||||
val view = LocalView.current
|
val view = LocalView.current
|
||||||
|
val animatedVisibilityScope = LocalNavAnimatedContentScope.current
|
||||||
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
|
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
|
||||||
|
|
||||||
val uiState = rememberEditorState(initialTodo = toDo)
|
val uiState = rememberEditorState(initialTodo = toDo)
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ class EditorState(val initialTodo: TodoEntity? = null) {
|
||||||
* 保存状态的 Saver 对象,用于适配 rememberSaveable
|
* 保存状态的 Saver 对象,用于适配 rememberSaveable
|
||||||
*/
|
*/
|
||||||
object Saver : androidx.compose.runtime.saveable.Saver<EditorState, Any> {
|
object Saver : androidx.compose.runtime.saveable.Saver<EditorState, Any> {
|
||||||
override fun SaverScope.save(value: EditorState): Any? {
|
override fun SaverScope.save(value: EditorState): Any {
|
||||||
return listOf(
|
return listOf(
|
||||||
value.initialTodo?.id ?: 0,
|
value.initialTodo?.id ?: 0,
|
||||||
value.toDoContent,
|
value.toDoContent,
|
||||||
|
|
@ -89,7 +89,7 @@ class EditorState(val initialTodo: TodoEntity? = null) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun restore(value: Any): EditorState? {
|
override fun restore(value: Any): EditorState {
|
||||||
val list = value as List<*>
|
val list = value as List<*>
|
||||||
val initialTodo = list[0] as? TodoEntity?
|
val initialTodo = list[0] as? TodoEntity?
|
||||||
return EditorState(initialTodo).apply {
|
return EditorState(initialTodo).apply {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
package cn.super12138.todo.ui.pages.main
|
package cn.super12138.todo.ui.pages.main
|
||||||
|
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.compose.animation.AnimatedVisibilityScope
|
|
||||||
import androidx.compose.animation.ExperimentalSharedTransitionApi
|
import androidx.compose.animation.ExperimentalSharedTransitionApi
|
||||||
import androidx.compose.animation.SharedTransitionScope
|
import androidx.compose.animation.SharedTransitionScope
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
|
@ -31,9 +30,11 @@ import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.navigation3.ui.LocalNavAnimatedContentScope
|
||||||
import androidx.window.core.layout.WindowSizeClass
|
import androidx.window.core.layout.WindowSizeClass
|
||||||
import cn.super12138.todo.R
|
import cn.super12138.todo.R
|
||||||
import cn.super12138.todo.constants.Constants
|
import cn.super12138.todo.constants.Constants
|
||||||
|
import cn.super12138.todo.logic.database.TodoEntity
|
||||||
import cn.super12138.todo.logic.datastore.DataStoreManager
|
import cn.super12138.todo.logic.datastore.DataStoreManager
|
||||||
import cn.super12138.todo.ui.components.ConfirmDialog
|
import cn.super12138.todo.ui.components.ConfirmDialog
|
||||||
import cn.super12138.todo.ui.pages.main.components.TodoTopAppBar
|
import cn.super12138.todo.ui.pages.main.components.TodoTopAppBar
|
||||||
|
|
@ -44,12 +45,13 @@ import cn.super12138.todo.ui.viewmodels.MainViewModel
|
||||||
fun MainPage(
|
fun MainPage(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
viewModel: MainViewModel,
|
viewModel: MainViewModel,
|
||||||
toTodoEditPage: () -> Unit,
|
toTodoEditPage: (TodoEntity?) -> Unit,
|
||||||
toSettingsPage: () -> Unit,
|
toSettingsPage: () -> Unit,
|
||||||
sharedTransitionScope: SharedTransitionScope,
|
sharedTransitionScope: SharedTransitionScope,
|
||||||
animatedVisibilityScope: AnimatedVisibilityScope,
|
|
||||||
windowSizeClass: WindowSizeClass = currentWindowAdaptiveInfo().windowSizeClass,
|
windowSizeClass: WindowSizeClass = currentWindowAdaptiveInfo().windowSizeClass,
|
||||||
) {
|
) {
|
||||||
|
val animatedVisibilityScope = LocalNavAnimatedContentScope.current
|
||||||
|
|
||||||
val toDos = viewModel.sortedTodos.collectAsState(initial = emptyList())
|
val toDos = viewModel.sortedTodos.collectAsState(initial = emptyList())
|
||||||
val selectedTodos = viewModel.selectedTodoIds.collectAsState()
|
val selectedTodos = viewModel.selectedTodoIds.collectAsState()
|
||||||
val showCompleted by DataStoreManager.showCompletedFlow.collectAsState(initial = Constants.PREF_SHOW_COMPLETED_DEFAULT)
|
val showCompleted by DataStoreManager.showCompletedFlow.collectAsState(initial = Constants.PREF_SHOW_COMPLETED_DEFAULT)
|
||||||
|
|
@ -91,10 +93,7 @@ fun MainPage(
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
expanded = expandedFab,
|
expanded = expandedFab,
|
||||||
onClick = {
|
onClick = { toTodoEditPage(null) },
|
||||||
viewModel.setEditTodoItem(null) // 每次添加待办前清除上一次已选待办
|
|
||||||
toTodoEditPage()
|
|
||||||
},
|
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.sharedElement(
|
.sharedElement(
|
||||||
sharedContentState = rememberSharedContentState(key = Constants.KEY_TODO_FAB_TRANSITION),
|
sharedContentState = rememberSharedContentState(key = Constants.KEY_TODO_FAB_TRANSITION),
|
||||||
|
|
@ -133,8 +132,7 @@ fun MainPage(
|
||||||
if (inSelectedMode) {
|
if (inSelectedMode) {
|
||||||
viewModel.toggleTodoSelection(item)
|
viewModel.toggleTodoSelection(item)
|
||||||
} else {
|
} else {
|
||||||
viewModel.setEditTodoItem(item)
|
toTodoEditPage(item)
|
||||||
toTodoEditPage()
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onItemLongClick = { viewModel.toggleTodoSelection(it) },
|
onItemLongClick = { viewModel.toggleTodoSelection(it) },
|
||||||
|
|
@ -171,8 +169,7 @@ fun MainPage(
|
||||||
if (inSelectedMode) {
|
if (inSelectedMode) {
|
||||||
viewModel.toggleTodoSelection(item)
|
viewModel.toggleTodoSelection(item)
|
||||||
} else {
|
} else {
|
||||||
viewModel.setEditTodoItem(item)
|
toTodoEditPage(item)
|
||||||
toTodoEditPage()
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onItemLongClick = { viewModel.toggleTodoSelection(it) },
|
onItemLongClick = { viewModel.toggleTodoSelection(it) },
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package cn.super12138.todo.ui.pages.settings
|
||||||
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,7 @@ package cn.super12138.todo.ui.viewmodels
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import cn.super12138.todo.TodoApp
|
import cn.super12138.todo.TodoApp
|
||||||
|
|
@ -51,8 +49,6 @@ class MainViewModel : ViewModel() {
|
||||||
}
|
}
|
||||||
|
|
||||||
val showConfetti = mutableStateOf(false)
|
val showConfetti = mutableStateOf(false)
|
||||||
var selectedEditTodo by mutableStateOf<TodoEntity?>(null)
|
|
||||||
private set
|
|
||||||
|
|
||||||
// 多选逻辑参考:https://github.com/X1nto/Mauth
|
// 多选逻辑参考:https://github.com/X1nto/Mauth
|
||||||
private val _selectedTodoIds = MutableStateFlow(listOf<Int>())
|
private val _selectedTodoIds = MutableStateFlow(listOf<Int>())
|
||||||
|
|
@ -82,10 +78,6 @@ class MainViewModel : ViewModel() {
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
fun setEditTodoItem(toDo: TodoEntity?) {
|
|
||||||
selectedEditTodo = toDo
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 切换待办的选择状态
|
* 切换待办的选择状态
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,9 @@ composeBom = "2025.11.00"
|
||||||
liveData = "1.9.4"
|
liveData = "1.9.4"
|
||||||
icons = "1.7.8"
|
icons = "1.7.8"
|
||||||
room = "2.8.3"
|
room = "2.8.3"
|
||||||
navigation = "2.9.6"
|
|
||||||
material3 = "1.5.0-alpha08"
|
material3 = "1.5.0-alpha08"
|
||||||
adaptive = "1.2.0"
|
adaptive = "1.2.0"
|
||||||
|
nav3Core = "1.0.0-rc01"
|
||||||
# AboutLibraries
|
# AboutLibraries
|
||||||
aboutLibsRelease = "13.1.0"
|
aboutLibsRelease = "13.1.0"
|
||||||
aboutLibsReleasePlugin = "13.1.0"
|
aboutLibsReleasePlugin = "13.1.0"
|
||||||
|
|
@ -49,7 +49,6 @@ androidx-datastore-preferences = { group = "androidx.datastore", name = "datasto
|
||||||
# Compose
|
# Compose
|
||||||
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
|
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
|
||||||
androidx-animation = { group = "androidx.compose.animation", name = "animation" }
|
androidx-animation = { group = "androidx.compose.animation", name = "animation" }
|
||||||
androidx-navigation = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigation" }
|
|
||||||
androidx-material3-adaptive = { group = "androidx.compose.material3.adaptive", name = "adaptive", version.ref = "adaptive" }
|
androidx-material3-adaptive = { group = "androidx.compose.material3.adaptive", name = "adaptive", version.ref = "adaptive" }
|
||||||
androidx-ui = { group = "androidx.compose.ui", name = "ui" }
|
androidx-ui = { group = "androidx.compose.ui", name = "ui" }
|
||||||
androidx-ui-android = { group = "androidx.compose.ui", name = "ui-android" }
|
androidx-ui-android = { group = "androidx.compose.ui", name = "ui-android" }
|
||||||
|
|
@ -61,6 +60,8 @@ androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit
|
||||||
androidx-material3 = { group = "androidx.compose.material3", name = "material3", version.ref = "material3" }
|
androidx-material3 = { group = "androidx.compose.material3", name = "material3", version.ref = "material3" }
|
||||||
androidx-material-icon-core = { group = "androidx.compose.material", name = "material-icons-core", version.ref = "icons" }
|
androidx-material-icon-core = { group = "androidx.compose.material", name = "material-icons-core", version.ref = "icons" }
|
||||||
androidx-material-icon-extended = { group = "androidx.compose.material", name = "material-icons-extended", version.ref = "icons" }
|
androidx-material-icon-extended = { group = "androidx.compose.material", name = "material-icons-extended", version.ref = "icons" }
|
||||||
|
androidx-navigation3-runtime = { module = "androidx.navigation3:navigation3-runtime", version.ref = "nav3Core" }
|
||||||
|
androidx-navigation3-ui = { module = "androidx.navigation3:navigation3-ui", version.ref = "nav3Core" }
|
||||||
|
|
||||||
# Room
|
# Room
|
||||||
androidx-room-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "room" }
|
androidx-room-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "room" }
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue