You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose:用点字符填充两Text间空白及Canvas点对齐问题

问题描述

现有如下Jetpack Compose代码,当前用weight=1f的Spacer填充两个Text组件间的空白,需要将空白替换为点字符“.”,实现从第一个Text到第二个Text的全宽度填充(示例效果:Text ............................... Text):

Row(
    modifier = Modifier
        .fillMaxWidth(),
    verticalAlignment = Alignment.CenterVertically
) {
    Text(
        text = titleSummary,
        fontSize = 16.sp,
        modifier = Modifier
            .padding(top = 24.dp)
            .padding(start = 16.dp)
    )

    Spacer(modifier = Modifier.weight(1f))
    
    Text(
        text = priceOrBonusText,
        fontSize = 16.sp,
        textDecoration = TextDecoration.LineThrough,
        modifier = Modifier
            .padding(top = 24.dp)
            .padding(end = 4.dp)
    )
}

更新问题:已通过Canvas绘制点,但绘制出的点位置上移,如何将其对齐到Text元素的底部边框?当前Canvas相关代码如下:

Canvas(
    modifier = Modifier
        .padding(horizontal = 4.dp)
        .padding(bottom = 6.dp)
        .align(Alignment.Bottom)
        .weight(1f)
) {
    renderingDots()
}
private fun DrawScope.renderingDots() {
    val dotRadius = 1.dp.toPx()
    val dotSpacing = 2.dp.toPx()
    val dotColor = Color(0xFF2F2F2F)

    val dotCount = (size.width / (dotRadius * 2 + dotSpacing)).toInt()

    repeat(dotCount) { index ->
        val dotX = (index * (dotRadius * 2 + dotSpacing)) + dotRadius
        drawCircle(
            dotColor,
            radius = dotRadius,
            center = Offset(dotX, size.height / 2)
        )
    }
}

解决方案

核心问题:对齐Text的底部基线

Text的底部边框对齐本质是对齐文字的基线(Baseline),直接用size.height / 2会让点居中,但Text的基线位置不在容器垂直中心,所以需要调整绘制逻辑或布局对齐方式。

方法1:修正Canvas绘制的Y坐标

调整Row的垂直对齐方式为底部对齐,同时把圆点的Y坐标设置为Canvas底部减去半径,让圆点贴紧底部,和Text底部对齐:

Row(
    modifier = Modifier
        .fillMaxWidth(),
    verticalAlignment = Alignment.Bottom // 改为底部对齐
) {
    Text(
        text = titleSummary,
        fontSize = 16.sp,
        modifier = Modifier
            .padding(top = 24.dp)
            .padding(start = 16.dp)
    )

    Canvas(
        modifier = Modifier
            .padding(horizontal = 4.dp)
            .weight(1f)
            .align(Alignment.Bottom) // 确保Canvas和Text底部对齐
    ) {
        renderingDots()
    }
    
    Text(
        text = priceOrBonusText,
        fontSize = 16.sp,
        textDecoration = TextDecoration.LineThrough,
        modifier = Modifier
            .padding(top = 24.dp)
            .padding(end = 4.dp)
    )
}

private fun DrawScope.renderingDots() {
    val dotRadius = 1.dp.toPx()
    val dotSpacing = 2.dp.toPx()
    val dotColor = Color(0xFF2F2F2F)

    val dotCount = (size.width / (dotRadius * 2 + dotSpacing)).toInt()
    // 将Y坐标设置为Canvas底部减去半径,让圆点贴紧底部
    val dotY = size.height - dotRadius

    repeat(dotCount) { index ->
        val dotX = (index * (dotRadius * 2 + dotSpacing)) + dotRadius
        drawCircle(
            dotColor,
            radius = dotRadius,
            center = Offset(dotX, dotY)
        )
    }
}

方法2:用Text组件生成点(更简洁)

如果不需要自定义圆点样式,直接用Text组件生成重复的点,配合weight=1f和textAlign=TextAlign.Justify,可以快速实现效果:

Row(
    modifier = Modifier
        .fillMaxWidth(),
    verticalAlignment = Alignment.CenterVertically
) {
    Text(
        text = titleSummary,
        fontSize = 16.sp,
        modifier = Modifier
            .padding(top = 24.dp)
            .padding(start = 16.dp)
    )

    Text(
        text = ".".repeat(100), // 足够多的点,超出部分会被截断
        fontSize = 16.sp,
        color = Color(0xFF2F2F2F),
        modifier = Modifier
            .padding(horizontal = 4.dp)
            .weight(1f),
        textAlign = TextAlign.Justify // 让点均匀填充宽度
    )
    
    Text(
        text = priceOrBonusText,
        fontSize = 16.sp,
        textDecoration = TextDecoration.LineThrough,
        modifier = Modifier
            .padding(top = 24.dp)
            .padding(end = 4.dp)
    )
}

内容的提问来源于stack exchange,提问作者Сергей Беляков

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 16:12:49