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

Flutter TextField删全内容触发RangeError及保留固定前缀求助

解决Flutter TextField退格RangeError及固定前缀无法删除问题

问题原因

当文本缩短到只剩固定前缀“Rs. ”时,继续执行删除操作会不断缩减文本长度,直到长度为0后执行substring(0, -1),触发RangeError (end): Invalid value: Only valid value is 0: -1。同时当前逻辑无法阻止前缀被删除。

解决方案

  • 限制删除范围:仅当文本长度大于固定前缀长度时才执行删除,避免触及前缀及产生负数索引
  • 监听文本变化:确保前缀始终存在,防止意外修改

修改后代码

import 'package:flutter/material.dart';
import 'package:sadapay_clone/screens/homepage.dart';
import 'package:sadapay_clone/widgets/numpad.dart';

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

  @override
  State<SendMoney> createState() => _SendMoneyState();
}

class _SendMoneyState extends State<SendMoney> {
  final TextEditingController _myController = TextEditingController();
  // 统一管理固定前缀
  final String _fixedPrefix = 'Rs. ';

  @override
  void initState() {
    super.initState();
    _myController.text = _fixedPrefix;
    // 添加监听,确保前缀不被修改
    _myController.addListener(() {
      final currentText = _myController.text;
      if (!currentText.startsWith(_fixedPrefix)) {
        _myController.text = _fixedPrefix + currentText.replaceAll(_fixedPrefix, '');
        // 将光标固定在文本末尾
        _myController.selection = TextSelection.fromPosition(
          TextPosition(offset: _myController.text.length),
        );
      }
    });
  }

  @override
  void dispose() {
    _myController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color.fromARGB(255, 255, 129, 129),
      body: Column(
        children: [
          const SizedBox(height: 75),
          SizedBox(
            height: 70,
            child: Center(
              child: TextField(
                controller: _myController,
                textAlign: TextAlign.center,
                showCursor: false,
                style: const TextStyle(
                  color: Colors.white,
                  fontSize: 40,
                ),
                keyboardType: TextInputType.none,
                decoration: const InputDecoration(border: InputBorder.none),
                enabled: false,
              ),
            ),
          ),
          NumPad(
            controller: _myController,
            delete: () {
              final currentLength = _myController.text.length;
              // 仅当文本长度超过前缀长度时执行删除
              if (currentLength > _fixedPrefix.length) {
                _myController.text = _myController.text.substring(0, currentLength - 1);
              }
            },
            onSubmit: () {},
          ),
          // 补充原有代码中缺失的闭合组件
        ],
      ),
    );
  }
}

关键修改说明

  1. 用_fixedPrefix常量统一管理前缀,方便后续维护
  2. 删除逻辑增加长度判断,彻底避免删到前缀及负数索引问题
  3. 控制器监听确保文本始终以固定前缀开头,防止意外修改
  4. 增加dispose方法释放控制器资源,避免内存泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 08:38:49