六、使用Jetpack Compsoe编写一个写小说的Android应用:章节列表页面优化与ConstraintLayout约束解耦

本篇和上一篇基本差不多,都是对原来的行列布局进行修改,毕竟ConstraintLayout十分滴好用。

1、页面布局优化

这次先放预览图

本篇要实现的就是优化一下LazyColumn中item的布局,就是每一个小项的布局。

注意:这里因为没在Entities文件中对Chapter数据类进行修改调整,所以就没加字数的数据列。

首先定义一个数据集:

val chapter:List<Chapter> = listOf(
        Chapter(0,1,1,"第1章","","2023-11-30 8:00:00"),
        Chapter(1,1,2,"第2章","","2023-11-31 8:00:00"),
        Chapter(2,1,3,"第3章","","2023-11-32 8:00:00"),
    )

这里随便写了点数据,主要是为了看显示效果嘛,之后这些数据肯定是从数据库来的。

之后我们要做的就是列表块,如图:

话不多说,直接放代码,经过上一篇的学习相信你已经会操作约束布局了。

LazyColumn(modifier = Modifier.fillMaxSize()){
                items(chapter){
                    ConstraintLayout(modifier = Modifier.fillMaxWidth())
                    {
                        val (chapterNumber, chapterName, fontNumber, updateTime) = createRefs()
                        Text(text = it.chapterName!!,
                            modifier = Modifier.constrainAs(chapterNumber){
                                top.linkTo(parent.top, margin = 8.dp)
                                start.linkTo(parent.start, margin = 24.dp)
                        },
                            fontSize = 20.sp)
                        Text(text = it.chapterName!!,
                            modifier = Modifier.constrainAs(chapterName){
                            baseline.linkTo(chapterNumber.baseline)
                            start.linkTo(chapterNumber.end, margin = 16.dp)
                        },
                            fontSize = 20.sp)
                        Text(text = "3562字",
                            modifier = Modifier.constrainAs(fontNumber){
                            top.linkTo(chapterNumber.bottom, margin = 4.dp)
                            start.linkTo(chapterNumber.start, margin = 16.dp)
                        },
                            fontSize = 16.sp)
                        Text(
                            text = it.lastUpdateTime,
                            modifier = Modifier.constrainAs(updateTime){
                                baseline.linkTo(fontNumber.baseline)
                                end.linkTo(parent.end, margin = 16.dp)
                            },
                            fontSize = 16.sp
                        )
                    }
                }
            }

从代码中可以看到,我们遍历的数据列表是我们刚刚随便写的那个列表,而在括号内依然要用it来使用它。

这段代码也提供了一个参考,当之后有了数据库后,基本都是这种方式来获取某个参数了。

2、clickable()函数的使用

再提一个关键点

在主页时,我们通过Card的onClick属性来实现页面跳转,但是此时我们并没有Card布局,我们只有一个ConstraintLayout,它的属性里面并没有onClick这个属性。

那此时我们想通过点击列表项进行跳转的话,要怎么操作?

其实,modifier中提供了一个.clickable方法,只需要通过这个我们就可以进行跳转了。

比如我在约束布局中添加:

ConstraintLayout(modifier = Modifier
                        .fillMaxWidth()
                        .clickable {
                            navController.navigate("write_text_page/fic")
                        }){}

这两行代码就完成了页面的跳转。

当然,这里的writetextpage还没写,之后会有。

到这里就算完成本页面的优化了。

3、ConstraintLayout约束解耦

ConstraintLayout的基本使用相信大家都差不多会了,但是当控件比较多的时候,代码写在一块就显得非常的拥挤,比如我们要做的写文本的界面:

从上图可以看到,我们在工具栏topbar上安放了很多功能键,如果这些还是写在一个文件中,那么它的代码会非常长,可读性很差。

这时就要用到ConstraintLayout的解耦约束了,简单说就是把他的布局和约束单独写成一个函数,这样在主页面内只需要调用函数名即可。

接下来上WriteTextPage的topbar代码:

@Composable
fun WriteTextTopBar() {
    val constraintSet = decoupledConstraints(0.dp)
    ConstraintLayout(constraintSet, modifier = Modifier.fillMaxWidth()) {
        IconButton(
            onClick = { },
            //通知设置layoutId实现控制约束
            modifier = Modifier
                .height(50.dp)
                .width(40.dp)
                .layoutId("btn_back")
        ) {
            Image(
                painter = painterResource(id = R.drawable.btn_back),
                contentDescription = "add a book"
            )
        }
        IconButton(
            onClick = { },
            //通知设置layoutId实现控制约束
            modifier = Modifier
                .height(50.dp)
                .width(40.dp)
                .layoutId("btn_chapter_list")
        ) {
            Image(
                painter = painterResource(id = R.drawable.btn_chapter_list),
                contentDescription = "add a book"
            )
        }
        IconButton(
            onClick = { },
            //通知设置layoutId实现控制约束
            modifier = Modifier
                .height(50.dp)
                .width(40.dp)
                .layoutId("btn_save")
        ) {
            Image(
                painter = painterResource(id = R.drawable.btn_save),
                contentDescription = "add a book"
            )
        }
        IconButton(
            onClick = { },
            //通知设置layoutId实现控制约束
            modifier = Modifier
                .height(50.dp)
                .width(40.dp)
                .layoutId("btn_undo")
        ) {
            Image(
                painter = painterResource(id = R.drawable.btn_undo),
                contentDescription = "add a book"
            )
        }
        IconButton(
            onClick = { },
            //通知设置layoutId实现控制约束
            modifier = Modifier
                .height(50.dp)
                .width(40.dp)
                .layoutId("btn_redo")
        ) {
            Image(
                painter = painterResource(id = R.drawable.btn_redo),
                contentDescription = "add a book"
            )
        }
        Text(modifier = Modifier.layoutId("font_num"),
            text = "4000字",
            fontSize=20.sp)
        IconButton(
            onClick = { },
            //通知设置layoutId实现控制约束
            modifier = Modifier
                .height(50.dp)
                .width(40.dp)
                .layoutId("btn_item")
        ) {
            Image(
                painter = painterResource(id = R.drawable.btn_item),
                contentDescription = "add a book"
            )
        }
        IconButton(
            onClick = { },
            //通知设置layoutId实现控制约束
            modifier = Modifier
                .height(50.dp)
                .width(40.dp)
                .layoutId("btn_add")
        ) {
            Image(
                painter = painterResource(id = R.drawable.btn_add),
                contentDescription = "add a book"
            )
        }
    }
}

上半部分代码主要绑定组件,注意ConstraintLayout的传参有了些许变化。

下半部分:

// 约束布局函数只负责声明约束,不管其他的属性
private fun decoupledConstraints(margin: Dp): ConstraintSet {
    return ConstraintSet {
        val btn_back= createRefFor("btn_back")
        constrain(btn_back){
            top.linkTo(parent.top)
            bottom.linkTo(parent.bottom)
            start.linkTo(parent.start)
        }

        val btn_chapter_list= createRefFor("btn_chapter_list")
        constrain(btn_chapter_list){
            top.linkTo(parent.top)
            bottom.linkTo(parent.bottom)
            start.linkTo(btn_back.end)
        }

        val btn_save= createRefFor("btn_save")
        constrain(btn_save){
            top.linkTo(parent.top)
            bottom.linkTo(parent.bottom)
            start.linkTo(btn_chapter_list.end)
        }

        val btn_undo= createRefFor("btn_undo")
        constrain(btn_undo){
            top.linkTo(parent.top)
            bottom.linkTo(parent.bottom)
            start.linkTo(btn_save.end)
        }

        val btn_redo= createRefFor("btn_redo")
        constrain(btn_redo){
            top.linkTo(parent.top)
            bottom.linkTo(parent.bottom)
            start.linkTo(btn_undo.end)
        }

        val btn_add = createRefFor("btn_add")
        constrain(btn_add){
            top.linkTo(parent.top)
            bottom.linkTo(parent.bottom)
            end.linkTo(parent.end)
        }

        val btn_item= createRefFor("btn_item")
        constrain(btn_item){
            top.linkTo(parent.top)
            bottom.linkTo(parent.bottom)
            end.linkTo(btn_add.start)
        }

        val font_num= createRefFor("font_num")
        constrain(font_num){
            top.linkTo(parent.top)
            bottom.linkTo(parent.bottom)
            start.linkTo(btn_redo.end)
            end.linkTo(btn_item.start)
        }

    }
}

下半部分代码只负责控制约束,这样就将约束和布局解藕了。


注意:

val btn_back= createRefFor("btn_back")
        constrain(btn_back){
            top.linkTo(parent.top)
            bottom.linkTo(parent.bottom)
            start.linkTo(parent.start)
        }

这其中加粗的地方都要一致,不可val btnback= createRefFor("btn_back"),这样就会导致图标不显示。


在本来的页面函数中只需要调用即可:

Scaffold(modifier = Modifier.fillMaxWidth(),
        topBar = {
            TopAppBar(modifier = Modifier.height(50.dp), // 设置高度为 50dp
                title = { Text("") },
                colors = TopAppBarDefaults.smallTopAppBarColors(
                    containerColor = colorResource(id = R.color.toolbar_color)
                ),
                actions = {
                    WriteTextTopBar()
                })

        }
    ) {}

这样工具栏的效果就实现了!

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

HO灵

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

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

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

打赏作者

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

抵扣说明:

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

余额充值