九、使用Jetpack Compsoe编写一个写小说的Android应用:ViewModel使用

上一篇我们完成了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完成了最重要的一步!之后的操作就没那么有难度了!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HO灵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值