当前位置: 首页 > news >正文

和笔记相关的页面:编辑笔记和展示笔记 以及相关的viewmodel

1. 编辑笔记

  1. EditNotesScreen:这是一个可编辑笔记的屏幕,它接收一个NavController对象、一个书籍的bookId和一个可选的modifier参数。它使用了LocalNotesViewModel来管理笔记的数据。
  • 它首先定义了几个状态变量,包括是否显示对话框、编辑内容和当前正在编辑的笔记ID。
  • 使用LaunchedEffect来通知viewModel更新当前的bookId。
  • 使用Scaffold构建UI布局,包括一个悬浮按钮,用于触发添加新笔记的操作。
  • 在Column中构建了屏幕的主体布局,包括一个返回箭头图标和标题文本。
  • 如果showDialog为真,则显示一个AlertDialog,用于添加或编辑笔记。对话框中包含一个文本字段和一个确认按钮,用于提交笔记内容。
  • 使用observeAsState观察LiveData,获取当前书籍的所有笔记,并将其转换为Compose可用的状态。
  • 最后,调用NotesListScreen来显示笔记列表,允许用户点击笔记进行编辑或删除。
  1. NotesListScreen:这是一个显示笔记列表的Composable函数,它接收一个笔记列表notes,以及点击笔记时的回调onNoteClick和删除笔记时的回调onDeleteClick。
  • 使用LazyColumn构建一个懒加载的列表,为每条笔记创建一个Card组件。
  • 在每个Card中,使用Row布局显示笔记内容和一个删除按钮。笔记内容部分是可点击的,当点击时会调用onNoteClick回调。删除按钮点击时会调用onDeleteClick回调。

app/src/main/java/com/example/BookRecord/EditNoteScreen.kt:


@Composable
fun EditNotesScreen(navController: NavController,bookId: Int,modifier: Modifier = Modifier,
){var showDialog by remember { mutableStateOf(false) }var editingContent by remember { mutableStateOf("") }var currentEditingNoteId by remember { mutableStateOf<Int?>(null) }val viewModel = LocalNotesViewModel.current// 通知 ViewModel 更新当前 bookIdLaunchedEffect(bookId) {viewModel.setBookId(bookId)}Scaffold(floatingActionButton = {SmallAddButton(onClick = {// 在这里定义点击悬浮按钮后的动作editingContent = ""currentEditingNoteId = null // 表示添加新笔记showDialog = true})},floatingActionButtonPosition = FabPosition.End, // 将按钮放在右下角){ paddingValues ->Column(modifier = Modifier.padding(paddingValues).padding(16.dp)){Row(modifier = Modifier.fillMaxWidth(),verticalAlignment = Alignment.CenterVertically // 垂直居中对齐 Row 内的元素) {Column(modifier = Modifier.weight(1f),horizontalAlignment = Alignment.CenterHorizontally){Icon(imageVector = Icons.Filled.ArrowBack,contentDescription = "Back",tint = Color(0xFF6650a4),modifier = Modifier.size(40.dp).clickable {navController.navigate("Book")})}Column(modifier = Modifier.weight(9f)) {Text(text = "Edit Notes",fontSize = 25.sp,fontWeight = FontWeight.Bold,color = Color(0xFF6650a4),modifier = Modifier.padding(start = 20.dp) // 根据需要调整文本的右边距)}}// 显示添加或编辑笔记的对话框if (showDialog) {AlertDialog(onDismissRequest = { showDialog = false },title = { Text(if (currentEditingNoteId == null) "Add Note" else "Edit Note") },text = {TextField(value = editingContent,onValueChange = { editingContent = it },label = { Text("Content") })},confirmButton = {Button(onClick = {if (currentEditingNoteId == null) {// 添加新笔记viewModel.addNote(editingContent, bookId = bookId)} else {// 更新现有笔记currentEditingNoteId?.let { noteId ->// 注意:这里同样假设 bookId 不会是 null,以及你有一个接收 noteId 和 noteContent 的 editNote 方法。// 如果你的 editNote 方法需要不同的参数,请相应地调整。viewModel.editNote(noteId = noteId, editingContent, bookId = bookId) // 如果 bookId 是 null,则需要决定如何处理}}showDialog = false}) { Text("OK") }},dismissButton = {Button(onClick = { showDialog = false }) { Text("Cancel") }})}// 观察 LiveData 并将其转换为 Compose 可用的状态val notesByBookId = viewModel.notesByBookId.observeAsState(initial = emptyList())// 笔记列表...NotesListScreen(notes = notesByBookId.value,onNoteClick = { note ->editingContent = note.contentcurrentEditingNoteId = note.idshowDialog = true},onDeleteClick = { note ->viewModel.deleteNote(note)})}}}@Composable
fun NotesListScreen(notes: List<Note>,onNoteClick: (Note) -> Unit,onDeleteClick: (Note) -> Unit
) {LazyColumn {items(items = notes, key = { it.id }) { note ->Card(modifier = Modifier.padding(4.dp).fillMaxWidth()) {Row(modifier = Modifier.padding(8.dp).fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {Text(text = note.content,modifier = Modifier.weight(1f).clickable { onNoteClick(note) })IconButton(onClick = { onDeleteClick(note) }) { // 当点击删除按钮时,调用 onDeleteClickIcon(Icons.Default.Delete, contentDescription = "Delete")}}}}}
}

2. 展示笔记

  1. NotesScreen:这是一个用于查看笔记的屏幕,它接收一个NavController对象、一个书籍的bookId和一个可选的modifier参数。它使用了LocalNotesViewModel来管理笔记的数据。
  • 它首先定义了一个viewModel实例,用于获取和更新笔记数据。
  • 使用LaunchedEffect来通知viewModel更新当前的bookId,这样viewModel就可以加载与该书籍相关的笔记。
  • 使用Scaffold构建UI布局,这是Compose中的一个主要布局组件,用于提供材料设计的基础结构。
  • 在Column中构建了屏幕的主体布局,包括一个返回箭头图标和标题文本“View Notes”。
  • 返回箭头图标是可点击的,当用户点击时,它将使用NavController导航回到“Bookshelf”路由。
  • NoteList Composable函数被用来显示笔记列表,它接收一个笔记列表notes和一个modifier参数。
  1. NoteList:这是一个用于显示笔记列表的Composable函数,它接收一个笔记列表notes和一个可选的modifier参数。
  • 使用LazyColumn构建一个懒加载的列表,这是Compose中的一个性能优化组件,用于高效地显示大量列表项。
  • 列表中的每个项目都是一个Card组件,它显示了单个笔记的内容。
  • Column用于在卡片内部创建一个垂直布局,其中包含笔记的文本内容。

app/src/main/java/com/example/BookRecord/NotesScreen.kt:

@Composable
fun NotesScreen( // 重命名为 NotesScreennavController: NavController,bookId:Int,modifier: Modifier = Modifier,
) {// 示例笔记数据val viewModel = LocalNotesViewModel.current// 通知 ViewModel 更新当前 bookIdLaunchedEffect(bookId) {viewModel.setBookId(bookId)}// 观察 LiveData 并将其转换为 Compose 可用的状态val notesByBookId = viewModel.notesByBookId.observeAsState(initial = emptyList())Scaffold() {paddingValues ->Column(modifier = modifier.padding(paddingValues)){Row(modifier = Modifier.fillMaxWidth().padding(0.dp),verticalAlignment = Alignment.CenterVertically // 垂直居中对齐 Row 内的元素){Column(modifier = Modifier.weight(1f),horizontalAlignment = Alignment.CenterHorizontally){Icon(imageVector = Icons.Filled.ArrowBack,contentDescription = "Back",tint = Color(0xFF6650a4),modifier = Modifier.size(40.dp).clickable {navController.navigate("Bookshelf")})}Column(modifier = Modifier.weight(9f)) {Text(text = "View Notes",fontSize = 25.sp,fontWeight = FontWeight.Bold,color = Color(0xFF6650a4),modifier = Modifier.padding(start = 20.dp) // 根据需要调整文本的右边距)}}// 笔记列表NoteList(notes = notesByBookId.value, modifier = modifier.padding(paddingValues).padding(16.dp))}}
}@Composable
fun NoteList(notes: List<Note>, modifier: Modifier = Modifier) {LazyColumn(modifier = modifier) {items(items = notes, key = { note -> note.hashCode() }) { note ->Card(modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp),) {Column(modifier = Modifier.padding(16.dp)) {Text(text = note.content)}}}}
}

3. NoteViewModel.

  1. 构造函数:接收一个 Application 对象,并在初始化块中创建 NoteRepository 实例。NoteRepository 用于访问数据库和执行数据库操作。

  2. 数据库访问:通过 AppDatabase.getDatabase(application) 获取数据库实例,然后通过 noteDao() 方法获取 NotesDao 实例,这是与笔记表交互的接口。

  3. 当前选中的 BookId:使用 MutableLiveData<Int?> 来跟踪当前选中的书籍 ID (_currentBookId)。这个值用于确定要加载哪个书籍的笔记列表。

  4. 笔记列表:notesByBookId 是一个 LiveData<List> 属性,它使用 switchMap 函数根据当前的 bookId 获取对应的笔记列表。如果 bookId 为 null,则返回一个包含空列表的 MutableLiveData。

  5. 设置书籍 ID:setBookId 函数用于更新 _currentBookId 的值,这将触发 notesByBookId 重新获取对应书籍的笔记列表。

  6. 添加笔记:addNote 函数接收笔记内容和书籍 ID,然后在协程作用域内调用 repository.insert 方法将新笔记插入数据库。

  7. 删除笔记:deleteNote 函数接收一个 Note 对象,然后在协程作用域内调用 repository.delete 方法从数据库中删除该笔记。

  8. 编辑笔记:editNote 函数接收笔记 ID、更新后的笔记内容和书籍 ID,然后在协程作用域内调用 repository.update 方法更新数据库中的笔记。

  9. 协程处理:使用 viewModelScope.launch 在 ViewModel 的作用域内启动协程,以便在后台线程上执行数据库操作。

app/src/main/java/com/example/BookRecord/NoteViewModel.kt

package com.example.BookRecordimport android.app.Application
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.switchMap
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launchclass NoteViewModel(application: Application) : AndroidViewModel(application) {private val repository: NoteRepository// 使用 MutableLiveData 来跟踪当前选中的 bookIdprivate val _currentBookId = MutableLiveData<Int?>()init {val appDatabase = AppDatabase.getDatabase(application)val notesDao = appDatabase.noteDao()repository = NoteRepository(notesDao)}// 使用 switchMap 来根据当前的 bookId 获取对应的笔记列表val notesByBookId: LiveData<List<Note>> = _currentBookId.switchMap { bookId ->bookId?.let {repository.getNotesByBookId(it)} ?: MutableLiveData(emptyList())}fun setBookId(bookId: Int) {_currentBookId.value = bookId}// 添加笔记需要提供bookIdfun addNote(noteContent: String, bookId: Int) = viewModelScope.launch {val newNote = Note(content = noteContent, bookId = bookId)repository.insert(newNote)}// 删除笔记fun deleteNote(note: Note) = viewModelScope.launch {repository.delete(note)}// 编辑笔记fun editNote(noteId: Int, noteContent: String, bookId: Int) = viewModelScope.launch {val noteToUpdate = Note(id = noteId, content = noteContent, bookId = bookId)repository.update(noteToUpdate)}
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • C++面试模拟01
  • 三维点云处理(C++)学习记录——PDAL
  • 【git】
  • Mysql基础——DML
  • mysql Field ‘ssl_cipher‘ doesn‘t have a default value的解决
  • OpenFeign:Spring Cloud中的声明式HTTP客户端
  • 2024年汉字小达人区级自由报名备考冲刺:今年官方模拟题练一练
  • SpringSecurity 5
  • 2024.9.18
  • Collections.synchronizedList()
  • 课程首发 | 微软 AI 创新日推荐官招募中
  • General OCR Theory: Towards OCR-2.0 via a Unified End-to-end Model
  • 如何使用ssm实现基于vue.js的购物商场的设计与实现+vue
  • git push命令报错:the remote end hung up unexpectedly
  • 【Transformer深入学习】之一:Sinusoidal位置编码的精妙
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • 11111111
  • Apache Pulsar 2.1 重磅发布
  • eclipse的离线汉化
  • ES10 特性的完整指南
  • ES2017异步函数现已正式可用
  • es6要点
  • Git同步原始仓库到Fork仓库中
  • Java多线程(4):使用线程池执行定时任务
  • JS基础篇--通过JS生成由字母与数字组合的随机字符串
  • Linux快速复制或删除大量小文件
  • python_bomb----数据类型总结
  • Python连接Oracle
  • Spring框架之我见(三)——IOC、AOP
  • Yeoman_Bower_Grunt
  • 实现简单的正则表达式引擎
  • 使用 5W1H 写出高可读的 Git Commit Message
  • 王永庆:技术创新改变教育未来
  • 怎么将电脑中的声音录制成WAV格式
  • kubernetes资源对象--ingress
  • Unity3D - 异步加载游戏场景与异步加载游戏资源进度条 ...
  • # 服务治理中间件详解:Spring Cloud与Dubbo
  • #Datawhale AI夏令营第4期#AIGC文生图方向复盘
  • $refs 、$nextTic、动态组件、name的使用
  • (2015)JS ES6 必知的十个 特性
  • (51单片机)第五章-A/D和D/A工作原理-A/D
  • (7)摄像机和云台
  • (ZT)出版业改革:该死的死,该生的生
  • (二)JAVA使用POI操作excel
  • (分布式缓存)Redis分片集群
  • (附源码)node.js知识分享网站 毕业设计 202038
  • (附源码)springboot掌上博客系统 毕业设计063131
  • (力扣)1314.矩阵区域和
  • (面试必看!)锁策略
  • (三)Kafka 监控之 Streams 监控(Streams Monitoring)和其他
  • (十八)Flink CEP 详解
  • (十八)SpringBoot之发送QQ邮件
  • (四) Graphivz 颜色选择
  • (五)activiti-modeler 编辑器初步优化
  • (一)模式识别——基于SVM的道路分割实验(附资源)