十八、使用Jetpack Compsoe编写一个写小说的Android应用:页面切换功能实现(底部工具栏使用BottomAppBar)

如果是仔细研究过Scaffold的小伙伴相信看一眼标题就大概知道怎么实现了,所以说到底主要还是功能实现,界面实现起来还是比较简单的。

先说说为什么要做这个功能:

首先我们已经有了drawer,有了章节列表页,为何还要做一个看似鸡肋的功能?

其实是我懒,比如说我想翻到上一章,那么目前来看我有两种方法:

1、点击章节列表的drawer,然后选中对应的上一章,点击

2、点击返回键,返回章节列表页面,找到我想看的章节并打开

发现了吗?这么做其实有一丢丢麻烦,我就是跳到上一章而已,却要操作这么多步骤,为什么就没有一个按钮让我点一下就行呢?我又不是跳到前十章去是吧?

所以说这个功能还是稍微有点意义的。

1、界面设计

其实Scaffold已经提供了对应的接口,点开它的定义文件就能看到。

所以说,我们直接在WriteTextPage中添加就行了

 

这里的content我小提一嘴,这个其实可有可无,这里我是写成了

Scaffold(
            topBar = {},
            bottomBar = {},
            content = { innerPadding -> }
            
        )

 但是如果你写成这样也是可以的

Scaffold(
            topBar = {},
            bottomBar = {},
            ){ innerPadding -> }
            
        

其实整个添加BottomAppBar的过程和TopBar是一模一样的,接下来就是创建一个BottomAppBar了

其中的WriteTextBottomBar就是一个布局函数,包括布局和约束两部分

 最终实现的效果就是这样,代码后面和功能一块放。

2、功能实现

 接下来就是功能实现了,我想要让它们达到如下效果:

1、上翻箭头(左侧箭头)在第一章时无法点击,下翻箭头在最新章时无法点击

2、页面初始化时会根据章节号初始化按钮状态

3、使用drawer跳转页面时,按钮状态也能按第一条更新

所以其实就是将第一条功能实现了其他都好办!

 所以直接上代码,先看页面初始化的:(注意我将其他代码删去了)

        // 上下切换按钮状态
    val lastChapterState = remember { mutableStateOf(false) }
    val nextChapterState = remember { mutableStateOf(false) }
if (initialState.value) {
        chapterId.value = chapterIdTrans!!

        LaunchedEffect(key1 = Any(), block = {
            val chapter = viewModel.getChapterById(fictionId, chapterId.value)
            val nextChapter = viewModel.getChapterById(fictionId, chapterId.value + 1)
            if (chapterId.value == 1) {
                if (nextChapter == null) {
                    lastChapterState.value = false
                    nextChapterState.value = false
                } else {
                    lastChapterState.value = false
                    nextChapterState.value = true
                }
            } else {
                if (nextChapter == null) {
                    lastChapterState.value = true
                    nextChapterState.value = false
                } else {
                    lastChapterState.value = true
                    nextChapterState.value = true
                }
            }

            initialState.value = false

}

这里要做两件事,查询本章章节号和下一章章节号,如果它是第一章,就得确认有没有第二章,如果不是第一章,那也得确认有没有第二章。

而在drawer中,就直接加在clickable函数中就好了,切勿直接复制,括号少了很多,代码基本和上面的一样

ModalNavigationDrawer(
        drawerState = drawerState,
        gesturesEnabled = drawerState.isOpen,
        drawerContent = {
            Box(
                modifier = Modifier
                    .safeDrawingPadding()
                    .width(330.dp)
                    .background(Color.White)
            ) {
                LazyColumn(modifier = Modifier.fillMaxSize()) {
                    items(chaptersDrawer) {
                        ConstraintLayout(modifier = Modifier
                            .fillMaxWidth()
                            .clickable {
                                chapterId.value = it.chapterId
   
                                scope.launch {
                                    drawerState.close()
                                    val nextChapter =
                                        viewModel.getChapterById(fictionId, chapterId.value + 1)
                                    if (chapterId.value == 1) {
                                        if (nextChapter == null) {
                                            lastChapterState.value = false
                                            nextChapterState.value = false
                                        } else {
                                            lastChapterState.value = false
                                            nextChapterState.value = true
                                        }
                                    } else {
                                        if (nextChapter == null) {
                                            lastChapterState.value = true
                                            nextChapterState.value = false
                                        } else {
                                            lastChapterState.value = true
                                            nextChapterState.value = true
                                        }
                                    }

最后才到按钮这里,

IconButton(
            onClick = {
                val chapterTextNumber =
                    contentText.value.text.replace("\\s".toRegex(), "").length
                viewModel.updateChapter(fictionId,chapterId.value,titleText.value.text,contentText.value.text,chapterTextNumber)
                chapterId.value -= 1
                scope.launch {
                    val chapter = viewModel.getChapterById(
                        fictionId,
                        chapterId.value
                    )
                    titleText.value =
                        TextFieldValue(chapter!!.chapterName)
                    contentText.value =
                        TextFieldValue(chapter.chapterText)
                    if(chapterId.value == 1) {
                        lastChapterState.value = false
                        nextChapterState.value = true
                    } else {
                        lastChapterState.value = true
                        nextChapterState.value = true
                    }
                }
            },
            enabled = lastChapterState.value,
            modifier = Modifier
                .height(50.dp)
                .width(40.dp)
                .layoutId("btnLastChapter")
        ) {
            Icon(
                painter = painterResource(id = R.drawable.btn_last_chapter),
                contentDescription = "last chapter"
            )
        }
        IconButton(
            onClick = {
                val chapterTextNumber =
                    contentText.value.text.replace("\\s".toRegex(), "").length
                viewModel.updateChapter(fictionId,chapterId.value,titleText.value.text,contentText.value.text,chapterTextNumber)
                scope.launch {
                    chapterId.value += 1
                    val chapter = viewModel.getChapterById(
                        fictionId,
                        chapterId.value
                    )
                    titleText.value =
                        TextFieldValue(chapter!!.chapterName)
                    contentText.value =
                        TextFieldValue(chapter.chapterText)
                    val nextChapter = viewModel.getChapterById(
                        fictionId,
                        chapterId.value + 1
                    )
                    if (nextChapter == null) {
                        lastChapterState.value = true
                        nextChapterState.value = false
                    } else {
                        lastChapterState.value = true
                        nextChapterState.value = true
                    }

                }
            },
            enabled = nextChapterState.value,
            modifier = Modifier
                .height(50.dp)
                .width(40.dp)
                .layoutId("btnNextChapter")
        ) {
            Icon(
                painter = painterResource(id = R.drawable.btn_next_chapter),
                contentDescription = "next chapter"
            )
        }

按钮中给它添加了保存功能,毕竟比较容易误触,所以加个保存功能

然后上一章就是id减一,下一章就是id加一

还要注意enabled的值要改成对应变量的值

 这样就大功告成了,来看效果:

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

HO灵

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

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

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

打赏作者

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

抵扣说明:

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

余额充值