上一篇我们完成了ViewModel和Room数据库操作的关联,那么这一篇就来说一下要怎么在具体的页面函数中使用它们。
1、页面函数的参数传递
fun FictionNamePage(navController: NavController,
viewModel: FictionNameViewModel = viewModel(factory = AppViewModelProvider.Factory))
在页面函数中我们新加一个参数:
viewModel: FictionNameViewModel = viewModel(factory = AppViewModelProvider.Factory)
为什么要这么写我也不太清楚,这是抄的官方案例。
添加了viewModel之后,就能在对应的按钮的click事件中添加数据库操作
先定义一个持久变量:
var fictionName by remember { mutableStateOf("") }
现在我在对勾按钮的click中添加插入书籍的代码:
IconButton(onClick = {
viewModel.insertBook(fictionName)
},modifier = Modifier.size(50.dp)) {
Image(painter = painterResource(id = R.drawable.btn_finish),
contentDescription = "add a book" )
}
这样就完成了数据插入操作。
从viewModel这个参数中可以发现,我们需要一个AppViewModelProvider,参考官方案例AppViewModelProvider代码为:
/**
* Provides Factory to create instance of ViewModel for the entire Inventory app
*/
object AppViewModelProvider {
val Factory = viewModelFactory {
// Initializer for ItemEntryViewModel
initializer {
FictionNameViewModel(fictionApplication()
.container.fictionNameRepository)
}
// // Initializer for ItemDetailsViewModel
// initializer {
// ItemDetailsViewModel(
// this.createSavedStateHandle()
// )
// }
// // Initializer for HomeViewModel
// initializer {
// HomeViewModel()
// }
}
}
/**
* Extension function to queries for [Application] object and returns an instance of
* [FictionApplication].
*/
fun CreationExtras.fictionApplication(): FictionApplication =
(this[AndroidViewModelFactory.APPLICATION_KEY] as FictionApplication)
(可以看到我注释了很多内容,那些就是原来案例里的代码)
这几句代码我不太理解,下面的CreationExtras.fictionApplication()函数像是将AndroidViewModelFactory和FictionApplication 绑定,具体是啥我也不明白,有大佬明白的话求告知。
上面代码可以看到就是初始化ViewModel,以后写的ViewModel都要在这里初始化。
2、FictionApplication创建
从上面的代码可以发现,首先是FictionApplication类函数没有创建,所以继续参考案例给出代码:
class FictionApplication : Application() {
/**
* AppContainer instance used by the rest of classes to obtain dependencies
*/
lateinit var container: AppContainer
override fun onCreate() {
super.onCreate()
container = AppDataContainer(this)
}
}
这个函数从表面上来看就是在app创建的时候(调用onCreate方法)创建了一个app的数据容器。
3、AppContainer创建
那么这时又多出来一个AppContainer,所以继续参考案例给出代码:
/**
* App container for Dependency injection.
*/
interface AppContainer {
val fictionNameRepository: FictionNameRepository
}
/**
* [AppContainer] implementation that provides instance of [OfflineItemsRepository]
*/
class AppDataContainer(private val context: Context) : AppContainer {
/**
* Implementation for [ItemsRepository]
*/
override val fictionNameRepository: FictionNameRepository by lazy {
OfflineFictionNameRepository(AppDatabase.getInstance(context).fictionNameDao())
}
}
从这个代码中可以看出,AppDataContainer才真正将数据库实例化的fictionNameDao接口获取到了,这时,实际的数据库才被创建并且创建了接口,有了这个函数,viewmodel的操作才真正指向了实例化的数据库。
至于AppContainer,应该是为了AppDataContainer实现而创建的一个接口函数,具体深意似懂非懂。
到此时就差最后一步了!
4、AndroidManifest添加
在后面调试中总是报错,后来百度才发现这个文件里竟然也要添加东西!
android:name=".FictionApplication"
主要添加这一句,添加位置如图
之后就可以尝试运行了!
5、Room数据库数据查看
运行代码后,打开下方的App Inspection
我们操作的是fictionData这个数据表,所以打开这个表,你的数据库应该是空的,我这是添加了几个做测试用。
之后我们跳转到创建小说页面输入kksk然后点击右上角的对勾按钮,然后点击左下角的刷新,就能看到数据库中有数据了!
完成!app完成了最重要的一步!之后的操作就没那么有难度了!