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,提问作者Сергей Беляков
相关产品推荐
相关产品推荐

