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

如何在Jetpack Compose的TextField中绘制平行横线实现记事本效果

带横线的输入框

实现思路
  • 无需修改TextField内部逻辑,直接给组件添加背景绘制层即可,通过Canvas API绘制平行横线,不会影响TextField原有输入、光标、选中交互逻辑。
  • 横线间距需和TextField的文字行高严格对齐,避免文字和横线错位。
完整实现代码
import androidx.compose.foundation.drawBehind
import androidx.compose.material.TextField
import androidx.compose.material.TextFieldDefaults
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

@Composable
fun LinedNoteTextField(
    value: String,
    onValueChange: (String) -> Unit,
    modifier: Modifier = Modifier,
    lineColor: Color = Color(0xFFE5E5E5),
    lineHeight: TextUnit = 24.sp,
    lineStrokeWidth: Dp = 1.dp
) {
    TextField(
        value = value,
        onValueChange = onValueChange,
        modifier = modifier.drawBehind {
            val lineHeightPx = lineHeight.toPx()
            // 计算需要绘制的横线总数量
            val lineCount = (size.height / lineHeightPx).toInt() + 1
            val strokePx = lineStrokeWidth.toPx()
            repeat(lineCount) { index ->
                val yPosition = (index + 1) * lineHeightPx
                drawLine(
                    color = lineColor,
                    start = Offset(0f, yPosition),
                    end = Offset(size.width, yPosition),
                    strokeWidth = strokePx
                )
            }
        },
        // 文字行高和横线间距保持一致
        textStyle = TextStyle(
            fontSize = 16.sp,
            lineHeight = lineHeight
        ),
        // 隐藏TextField默认的底部指示器、设置背景透明
        colors = TextFieldDefaults.textFieldColors(
            backgroundColor = Color.Transparent,
            focusedIndicatorColor = Color.Transparent,
            unfocusedIndicatorColor = Color.Transparent,
            disabledIndicatorColor = Color.Transparent
        )
    )
}
调用示例
@Composable
fun NoteEditScreen() {
    var noteContent by remember { mutableStateOf("") }
    LinedNoteTextField(
        value = noteContent,
        onValueChange = { noteContent = it },
        modifier = Modifier
            .fillMaxSize()
            .padding(horizontal = 16.dp, vertical = 8.dp)
    )
}
可选优化项
  • 若需要实现和实体记事本一致的左侧装订线,可在drawBehind中额外绘制一条垂直红色实线,x轴固定在8dp左右的位置即可。
  • 若文字和横线位置错位,可调整TextField的padding属性,将文字整体上下移动,保证文字落在两条横线中间。
  • 组件自带滚动适配,内容超出组件高度滚动时,横线会随内容同步滚动,无需额外适配。

内容的提问来源于stack exchange,提问作者Arpit Shukla

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 19:18:03