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

加入图书页面以及和图片相关的viewmodel代码

1.加入图书页面

  1. AddBookScreen:这是一个用于添加书籍的屏幕,它接收一个NavController对象和一个可选的modifier参数。
  • 它首先定义了一个focusManager,用于管理键盘操作。
  • 使用mutableStateOf创建了一个状态变量searchText,用于存储搜索框中的文本。
  1. Column:使用Column构建了屏幕的主体布局,并设置了内边距。

  2. Row:在Column中,使用Row布局创建了一个包含返回图标和搜索框的水平布局。

  • IconButton:定义了一个返回图标按钮,点击时会调用navController.popBackStack()返回上一个导航目的地。
  • Spacer:在返回图标和搜索框之间添加了空间。
  1. OutlinedTextField:定义了一个带有轮廓的文本字段,用于输入搜索内容。
  • value和onValueChange参数用于控制文本字段的值和更改时的回调。
  • label提供了文本字段的标签,指示用户可以搜索书名或作者。
  • modifier用于设置文本字段的背景颜色和圆角形状。
  • colors参数自定义了文本字段的颜色,包括光标颜色、聚焦时的边框颜色和非聚焦时的边框颜色。
  • singleLine设置为true,表示文本字段为单行输入。
  • trailingIcon在文本字段的右侧显示一个清除图标,当文本字段中有内容时显示,点击可以清空文本字段。
  • keyboardActions定义了键盘操作,其中onSearch用于处理搜索逻辑,同时隐藏键盘。
  • keyboardOptions设置了键盘的输入模式为搜索,通常在键盘上显示一个搜索按钮。

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

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AddBookScreen(navController: NavController,modifier: Modifier = Modifier,
) {// The focus manager to handle the keyboard actionsval focusManager = LocalFocusManager.current// State for search textvar searchText by remember { mutableStateOf("") }Column(modifier = modifier.padding(12.dp)) {Row(modifier = Modifier.fillMaxWidth(),verticalAlignment = Alignment.CenterVertically) {// Back icon with a larger touch target for better accessibilityIconButton(onClick = { navController.popBackStack() },modifier = Modifier.size(35.dp)) {Icon(imageVector = Icons.Filled.ArrowBack,contentDescription = "Back",tint = Color(0xFF6650a4))}Spacer(modifier = Modifier.width(10.dp)) // Add space between the icon and the search bar// Search input fieldOutlinedTextField(value = searchText,onValueChange = { searchText = it },label = { Text("Search by title, author", color = Color(0xFF6650a4)) },modifier = Modifier.fillMaxWidth().background(Color(0xFFF2F2F2), RoundedCornerShape(20.dp)), // 直接在这里设置背景颜色和形状shape = RoundedCornerShape(20.dp), // 设置输入框的形状colors = TextFieldDefaults.outlinedTextFieldColors(
//                    backgroundColor = Color(0xFFF2F2F2),cursorColor = Color(0xFF6650a4),focusedBorderColor = Color(0xFF6650a4),unfocusedBorderColor = Color(0xFF6650a4)),singleLine = true,trailingIcon = {if (searchText.isNotEmpty()) {IconButton(onClick = { searchText = "" }) {Icon(imageVector = Icons.Filled.Clear,contentDescription = "Clear",tint = Color(0xFF6650a4))}}},keyboardActions = KeyboardActions(onSearch = {focusManager.clearFocus() // Hide the keyboard// TODO: Implement the search logic here}),keyboardOptions = KeyboardOptions.Default.copy(imeAction = ImeAction.Search))}// TODO: Add the rest of your UI components here}
}

2. BookViewModel

  1. BookStatus枚举:定义了书籍的三种状态,分别是正在阅读(READING)、已阅读(READ)和搁置(ON_HOLD)。

  2. BookViewModel类:这是一个继承自AndroidViewModel的视图模型类,用于管理和存储书籍数据。

  • 类的初始化块中,通过传入的Application对象获取了数据库的访问对象bookDao和noteDao,这些对象用于与数据库进行交互。
  • bookRepository和noteRepository是用于数据操作的仓库类实例,它们封装了对数据库的直接访问。
  • currentUserUID存储了当前登录用户的用户ID,用于将书籍与用户关联。
  • allBooks是一个LiveData对象,用于观察所有书籍的数据变化。
  • bookCounts是一个MutableLiveData对象,用于存储和更新书籍状态的计数。
  • readingBooks、completeBooks和layasideBooks是MediatorLiveData对象,它们根据书籍的状态过滤allBooks中的数据。
  • 在初始化块中,设置了MediatorLiveData的源为allBooks,并根据书籍的不同状态更新这些LiveData对象。
  • updateBookCounts方法用于更新书籍状态的计数,并将其存储在bookCounts中。
  • addBook方法用于添加新书籍到数据库中。
  • deleteBook方法用于从数据库中删除书籍。
  • updateBookStatus方法用于更新书籍的状态。
  • updateBookReadPage方法用于更新书籍的已阅读页数。
  • getNoteCountByBookId方法用于获取指定书籍的笔记数量。

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

enum class BookStatus {READING, // 正在阅读READ, // 已阅读ON_HOLD // 搁置
}//在类的初始化块中,通过传入应用程序的 Application 对象,获取了数据库的访问对象 bookDao 和 noteDao
class BookViewModel(application: Application) : AndroidViewModel(application) {private val bookDao = AppDatabase.getDatabase(application).bookDao()private val noteDao = AppDatabase.getDatabase(application).noteDao()private val bookRepository = BookRepository(bookDao, viewModelScope)private val noteRepository = NoteRepository(noteDao)var currentUserUID = FirebaseAuth.getInstance().currentUser?.uidval allBooks: LiveData<List<Book>> = bookRepository.allBooksval bookCounts = MutableLiveData<Map<String, Int>>()// 使用 MediatorLiveData 替代 Transformations.mapval readingBooks = MediatorLiveData<List<Book>>()val completeBooks = MediatorLiveData<List<Book>>()val layasideBooks = MediatorLiveData<List<Book>>()init {readingBooks.addSource(allBooks) { books ->readingBooks.value = books.filter { it.status == BookStatus.READING }}completeBooks.addSource(allBooks) { books ->completeBooks.value = books.filter { it.status == BookStatus.READ }}layasideBooks.addSource(allBooks) { books ->layasideBooks.value = books.filter { it.status == BookStatus.ON_HOLD }}// Update book countsupdateBookCounts()}private fun updateBookCounts() {val counts = mutableMapOf("have read" to 0, "lay aside" to 0, "reading" to 0)allBooks.observeForever { books ->counts["have read"] = books.count { it.status == BookStatus.READ }counts["lay aside"] = books.count { it.status == BookStatus.ON_HOLD }counts["reading"] = books.count { it.status == BookStatus.READING }bookCounts.value = counts}}// 添加新书籍fun addBook(bookTitle: String, bookImage: String, author: String, pages: String, status: BookStatus, readPage: String, press: String,startTime: LocalDate) = viewModelScope.launch {val newBook = Book(userId = currentUserUID ?: "",//确保不会空,处理未登陆的情况title = bookTitle,image = bookImage,author = author,pages = pages,status = status,readpage = readPage,press = press,startTime = startTime // 设置当前日期为开始时间)bookRepository.insert(newBook)}// 删除书籍fun deleteBook(book: Book) = viewModelScope.launch {bookRepository.delete(book)}// 更新书籍状态fun updateBookStatus(book: Book, newStatus: BookStatus) = viewModelScope.launch {book.status = newStatusbookRepository.update(book)}// 更新已阅读页数fun updateBookReadPage(book: Book, readPage: String) = viewModelScope.launch {book.readpage = readPage // 确保属性名称与你的 Book 类一致bookRepository.update(book)}// 获取指定书籍的笔记数量fun getNoteCountByBookId(bookId: Int): LiveData<Int> {return noteRepository.getNoteCountByBookId(bookId)}}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • CSS学习18--伸缩布局
  • io_uring异步IO
  • TDengine 与飞腾腾锐 D2000 完成兼容互认证,推动国产软硬件深度融合
  • Azkaban、oozie、airflow、dolphinschduler 对比分析
  • Jupyter Notebook远程登录配置
  • 前端用html写excel文件直接打开
  • 二维码扫码模组国产麒麟系统C语言SDK二次开发
  • 【PostgreSQL数据库表膨胀的一些原因】
  • 系统架构师考试学习笔记第五篇——架构设计补充知识(26)论文写作
  • 响应式网站真的就只是多了一个媒体查询吗?
  • 数仓建设:为什么我们的数据容易被业务方质疑?
  • 关于codesys循环结束,循环内累加值仍不停止累加问题
  • 002集—— CAD划线并模拟向命令窗口发送命令(CAD—C#二次开发入门)
  • 绿荫德清,数聚聚宝汇智—聚宝用户夏日交流会圆满落幕
  • linux 操作系统下cu命令介绍和使用案例
  • 分享的文章《人生如棋》
  • 【知识碎片】第三方登录弹窗效果
  • 5分钟即可掌握的前端高效利器:JavaScript 策略模式
  • express.js的介绍及使用
  • Git学习与使用心得(1)—— 初始化
  • hadoop入门学习教程--DKHadoop完整安装步骤
  • Java读取Properties文件的六种方法
  • Mysql5.6主从复制
  • nodejs实现webservice问题总结
  • Promise面试题,控制异步流程
  • Redis提升并发能力 | 从0开始构建SpringCloud微服务(2)
  • 基于游标的分页接口实现
  • 检测对象或数组
  • 力扣(LeetCode)56
  • 前端之React实战:创建跨平台的项目架构
  • 一天一个设计模式之JS实现——适配器模式
  • 我们雇佣了一只大猴子...
  • (4)Elastix图像配准:3D图像
  • (4)事件处理——(2)在页面加载的时候执行任务(Performing tasks on page load)...
  • (DenseNet)Densely Connected Convolutional Networks--Gao Huang
  • (八)五种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (附源码)ssm户外用品商城 毕业设计 112346
  • (四)js前端开发中设计模式之工厂方法模式
  • (原创)攻击方式学习之(4) - 拒绝服务(DOS/DDOS/DRDOS)
  • (自用)仿写程序
  • .NET Framework、.NET Core 、 .NET 5、.NET 6和.NET 7 和.NET8 简介及区别
  • .NET Project Open Day(2011.11.13)
  • .Net 基于.Net8开发的一个Asp.Net Core Webapi小型易用框架
  • .NET 中让 Task 支持带超时的异步等待
  • .net(C#)中String.Format如何使用
  • .NET:自动将请求参数绑定到ASPX、ASHX和MVC(菜鸟必看)
  • .Net调用Java编写的WebServices返回值为Null的解决方法(SoapUI工具测试有返回值)
  • .NET多线程执行函数
  • 。Net下Windows服务程序开发疑惑
  • /etc/skel 目录作用
  • :中兴通讯为何成功
  • @CacheInvalidate(name = “xxx“, key = “#results.![a+b]“,multi = true)是什么意思
  • @ComponentScan比较
  • @requestBody写与不写的情况
  • @Value获取值和@ConfigurationProperties获取值用法及比较(springboot)