十二、使用Jetpack Compsoe编写一个写小说的Android应用:其他页面相互关联实现及LaunchedEffect使用

先梳理一下我们现在有的页面:

MainPage,主页面,用于显示小说列表
FictionNamePage,新建小说和修改小说名字页面
ChapterListPage,章节列表页面,主要显示一本小说下的所有章节以及这本小说的总字数
WriteTextPage,写小说页面,主要用来写小说内容,并实现保存新建等一系列基础功能

好,截止到目前为止,我们以及实现了主页面的列表显示,其他页面的UI设计,主页和新建小说页的相互跳转等功能。

那么本篇主要是顺着制作计划,完成ChapterListPage的跳转和列表实现。

1、ChapterListPage页面跳转实现

之前的代码编写中,跳转到ChapterListPage时,需要好几个参数,比如小说ID,小说名称,小说总字数等,但是这会导致页面传递参数的冗长,甚至在之后的页面跳转中携带的传递参数会进一步增加,导致代码逻辑混乱。

因此,为了解决这种传递参数混乱的问题,最终决定只传递小说ID这一个变量,剩余变量将在ChapterListPage中通过小说ID查询数据库获得。

所以,PageNavHost中代码如下:

// 给章节列表页指定路径
        composable(
            "chapter_list_page/{fictionId}",
            arguments = listOf(
                navArgument("fictionId") { type = NavType.IntType },
            )
        ) { backStackEntry ->
            ChapterListPage(navController, backStackEntry)
        }

MainPage中的导航路线也立刻变得十分简短:

Card(
      onClick = {
      // 导航到ChapterListPage可组合项
      navController.navigate("chapter_list_page/${it.fictionId}")
      },

参数传递过去,ChapterListPage中自然要进行接受:

val fictionId = backStackEntry.arguments?.getInt("fictionId")

返回键的代码:

IconButton(onClick = {
                            navController.popBackStack("main_page", false)
                                             }
                            ,modifier = Modifier.size(50.dp),) {
                            Image(painter = painterResource(id = R.drawable.btn_back),
                                contentDescription = "add a book" )
                        }

这样就完成了跳转。

2、ChapterListPage初始化页面时进行数据库查询获得相关数据

现在到达ChapterListPage的只有一个fictionId,我们必须要借助这个id来从数据库中获得对应的数据,但是涉及到数据库的操作都是suspend挂起函数,并不能在主线程中执行,我们要如何实现呢?

没错这时候就要用到一个函数【LaunchedEffect】:

fun ChapterListPage(
    navController: NavController, backStackEntry: NavBackStackEntry,
    viewModel: ChapterListViewModel = viewModel(factory = AppViewModelProvider.Factory)
                    ) {
    var fictionName  by remember { mutableStateOf("") }
    var textNumber  by remember { mutableStateOf(0) }
    val fictionId = backStackEntry.arguments?.getInt("fictionId")
    var showTextNumber = ""

    LaunchedEffect(key1 = Any(), block = {
        fictionName = viewModel.getBook(fictionId!!).fictionName
        textNumber = viewModel.getBook(fictionId).textNumber
        showTextNumber = if (textNumber>9999){
            "%.1f".format(textNumber.toFloat()/10000)+ "w字"
        }else{
            textNumber.toString() + "字"
        }
    })
}

LaunchedEffect这个函数,会在每次Composable函数重组时激活,其中可以运行挂起函数,它的key是一个标识符,当他等于Any的时候就是每次重组都会执行,换成固定值则只有对应值才会执行,但是我没太搞明白,现在特定条件下触发的话,最好用if语句。

而通过remember创建的变量就能很好的保存在其他线程上此变量的变化值。

所以通过这样,我们就能完美地在ChapterListPage中查询数据库了。

但是这样可能在性能上就不如传递参数快了,毕竟传递参数是直接拿来用,这种方式还得再查询一波,耗时是肯定的,之后会继续看看有没有什么更省力的方法。

  • 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、付费专栏及课程。

余额充值