十六、使用Jetpack Compsoe编写一个写小说的Android应用:第一次阶段总结

先捋一下我们目前已经实现的功能:

1、创建了四个界面分别为:

主页(MainPage)和小说名字页(FictionNamePage)



章节列表页(ChapterListPage)和写作页(WriteTextPage)

2、 实现了各个页面之间的跳转,包括从一个页面跳转到另一个页面,以及返回原页面等功能。

发现动图里有“主页”两个字的虚影,但是实际看的时候没有,可能是我录制不正确导致的,只看功能哈,忽略小瑕疵。 

3、小说名字页面(FictionNamePage)

实现了小说名字创建、修改,小说名字保存并在数据库中保存对应数据功能。

【所需功能已全部完成】

 4、主页面(MainPage)

实现了书籍列表展示功能(LazyColumn),并实现了删除、重命名、导出功能。

【剩余需实现功能:导入功能】

上面的操作基本都演示了,就不重新操作了。

5、 章节列表页(ChapterListPage)

主要就是显示章节信息,以及能进行章节删除,章节信息显示已经完成,详情见(六)。

之后也只需要将数据库中的对应信息填充到对应的接口上就行,这个应该不需要我在写一遍了吧,看看后面评论的反馈,有需要再写。

还有一个就是总字数了,这里得写一下

先确定一下思路:

思路一:

在保存章节内容的时候,顺便将字数信息更新,然后在ChapterListPage页面启动时去数据库里面找我们需要的数据。

思路二:

每次启动ChapterListPage页面时,对所有章节字数进行统计,计算后显示在对应区域。

显然思路一在代码上可能更加繁琐一点,因为采用这种思路的话,还要在删除章节的功能中加入更新字数的功能。

思路二相对简单一点,但是每次页面重组都会调用计算,导致出现较多的算力消耗,而且显示出来的界面也会因为各种函数而不断重组,导致调用次数会增加很多。

但是最后还是采用了思路二,因为一有点繁琐,而且在调试过程中会碰到不同协程调用顺序的问题,解决起来挺麻烦,不如这样简单点。

所以根据思路二,先要对数据库进行操作,获取所有章节的字数并求和:

class ChapterListViewModel(
    private val writeTextRepository: WriteTextRepository,
    private val chapterListRepository: ChapterListRepository,
    private val fictionNameRepository: FictionNameRepository
) : ViewModel() {

    suspend fun getBook(fictionId: Int): Book {
        val queryJob = viewModelScope.async {
            chapterListRepository.getBookOfId(fictionId)
        }
        return queryJob.await()
    }

    fun updateBook(fictionId: Int,textNumber:Int) {
        viewModelScope.launch {
            val book =
                fictionNameRepository.getBookOfId(fictionId)
            if (book != null) {
                fictionNameRepository.updateBook(
                    Book(book.numberId, fictionId, book.fictionName, textNumber)
                )
            }
        }
    }

    suspend fun getAllChaptersNumber(fictionId: Int): Int {

        val chapters = viewModelScope.async {
            writeTextRepository.getAllChapters(fictionId)
        }.await()

        return chapters.sumOf { it.chapterTextNumber }
    }
}

在ChapterListViewModel中获取所有章节并求和其字数,其中

interface WriteTextRepository {

    suspend fun getAllChapters(id: Int): List<Chapter>
}

之后就直接去 ChapterListPage中,想要在页面中自动触发,一下就应该想到LaunchEffect:

var showTextNumber by remember { mutableStateOf("") }
LaunchedEffect(key1 = Any(), block = {
        val specificBook = viewModel.getBook(fictionId!!)
        val textNumber = viewModel.getAllChaptersNumber(fictionId)
        val textNumberOrigin = specificBook.textNumber
        if (textNumber != textNumberOrigin){
            viewModel.updateBook(fictionId,textNumber)
        }

        showTextNumber = if (textNumber>9999){
            "%.1f".format(textNumber.toFloat()/10000)+ "w字"
        }else{
            textNumber.toString() + "字"
        }

    })

用于显示的Text:

Text(
      text = showTextNumber,
      fontSize = 16.sp)

你会发现我在里面加了一个判断,其实就是为了同步数据库和显示这边的数据,当场现算应该是错不了的,但是数据库中的可能是存的旧数据,所以如果不一致的话要更新一下数据库的数据。

 这样就完事了!

到这里的话,这一页的功能就全部完成了! 

6、写作页(WriteTextPage)

这页要实现的功能比较多,上面的工具栏按钮多,下面我也添加了工具栏,所以这一页先说目前为止实现了哪些功能:

  1. 返回上一页
  2. 保存
  3. 新加章,其中包括在最后一章新加和在中间章点击直接插入最新章等功能
  4. 抽屉显示
  5. 页面布局也算一个

那么接下来要实现的功能有:

  1. 撤销与反撤销
  2. 下方工具栏的页面切换
  3. 插入回车时多插入一行
  4. 实现类似edittext中的selection效果,就是跟随光标移动,如果你给TextField写一大段文字,你会发现它没有光标跟随的,每次都需要自己去滚,很不人性化。

以上就是本次总结,下次先从主页面的导出功能整起! 

  • 24
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值