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

Flutter TextField如何添加项目符号?现有方案存中间编辑换行问题

解决Flutter TextField中间换行自动添加项目符号的问题

原代码仅监测文本末尾的换行操作,无法处理在文本中间换行的场景。以下是修复后的完整实现,支持在任意位置换行时自动添加项目符号,同时避免重复添加和光标错乱问题:

import 'package:flutter/material.dart';

const String bullet = '\u2022';

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

  @override
  State<SampleView> createState() => _SampleViewState();
}

class _SampleViewState extends State<SampleView> {
  final TextEditingController controller = TextEditingController();
  bool _isUpdatingText = false; // 标记是否为主动修改文本,避免onChanged无限循环

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
        padding: const EdgeInsets.all(20.0),
        child: Center(
          child: TextField(
            minLines: 1,
            maxLines: 5,
            controller: controller,
            decoration: const InputDecoration(
              hintText: "Type Here..."
            ),
            onChanged: (value) {
              if (_isUpdatingText) return;

              List<String> lines = value.split('\n');
              bool needsUpdate = false;
              List<String> processedLines = [];

              for (String line in lines) {
                // 非空行开头无项目符号则自动添加
                if (line.isNotEmpty && !line.startsWith('$bullet ')) {
                  processedLines.add('$bullet $line');
                  needsUpdate = true;
                } else {
                  processedLines.add(line);
                }
              }

              if (needsUpdate) {
                _isUpdatingText = true;
                String newText = processedLines.join('\n');
                // 计算光标偏移量,避免光标跳转到末尾
                int originalOffset = controller.selection.base.offset;
                int addedChars = newText.length - value.length;
                int newOffset = (originalOffset + addedChars).clamp(0, newText.length);

                controller.text = newText;
                controller.selection = TextSelection.fromPosition(
                  TextPosition(offset: newOffset),
                );
                // 延迟重置标记,确保当前onChanged周期结束后再允许处理
                Future.microtask(() => _isUpdatingText = false);
              }
            },
          ),
        ),
      ),
    );
  }
}

关键改进点:

  • 逐行校验处理:将文本拆分为行单元,确保所有非空行都以项目符号开头,覆盖中间换行的场景。
  • 防循环机制:通过_isUpdatingText标记避免主动修改文本时触发重复的onChanged回调。
  • 光标位置维护:计算修改后光标应处的位置,保持编辑时的光标连贯性。
  • 空行兼容:空行不会自动添加项目符号,保留编辑灵活性。

内容的提问来源于stack exchange,提问作者Shruti Ramnandan Sharma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 07:45:16