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

Flutter中如何为多行TextField的每一行添加行号前缀?

给多行TextField每行添加行号前缀的实现方案

需求说明

需要为多行TextField的每一行添加带背景的行号前缀,效果为每行左侧显示带灰色背景的序号,与输入内容分隔开。

实现思路(以Flutter为例)

通过自定义组合Widget,将行号列表与TextField横向排列,同步行号数量与TextField的行数,同时保持行号与输入内容的垂直对齐:

  • 监听TextField内容变化,用控制器实时计算当前行数
  • 根据行数动态生成对应行号,设置统一的灰色背景样式
  • 让行号列表与TextField共用滚动控制器,保证滚动时两者同步

代码示例

import 'package:flutter/material.dart';

class NumberedTextField extends StatefulWidget {
  const NumberedTextField({super.key});

  @override
  State<NumberedTextField> createState() => _NumberedTextFieldState();
}

class _NumberedTextFieldState extends State<NumberedTextField> {
  final TextEditingController _inputController = TextEditingController();
  final ScrollController _scrollController = ScrollController();
  int _lineCount = 1;

  @override
  void initState() {
    super.initState();
    _inputController.addListener(_calcLineCount);
    _calcLineCount();
  }

  void _calcLineCount() {
    final inputText = _inputController.text;
    setState(() {
      _lineCount = inputText.isEmpty ? 1 : inputText.split('\n').length;
    });
  }

  @override
  void dispose() {
    _inputController.dispose();
    _scrollController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Row(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        // 行号区域
        Container(
          padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 12),
          color: Colors.grey[200],
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.end,
            children: List.generate(_lineCount, (index) {
              return Padding(
                padding: const EdgeInsets.only(bottom: 8),
                child: Text(
                  '${index + 1}',
                  style: TextStyle(color: Colors.grey[600]),
                ),
              );
            }),
          ),
        ),
        // 输入框区域
        Expanded(
          child: TextField(
            controller: _inputController,
            scrollController: _scrollController,
            maxLines: null,
            keyboardType: TextInputType.multiline,
            decoration: const InputDecoration(
              border: InputBorder.none,
              contentPadding: EdgeInsets.symmetric(horizontal: 12, vertical: 12),
            ),
          ),
        ),
      ],
    );
  }
}

// 使用示例
void main() {
  runApp(const MaterialApp(
    home: Scaffold(
      body: Padding(
        padding: EdgeInsets.all(20),
        child: NumberedTextField(),
      ),
    ),
  ));
}

关键细节

  • 行号与内容对齐:通过统一设置行号和TextField的内边距,保证每行垂直间距一致
  • 动态更新行号:监听文本变化,实时拆分换行符计算行数,自动更新行号列表
  • 滚动同步:两者共用滚动控制器,滚动时行号会跟随输入内容同步移动

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 02:20:25