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

Flutter自定义文本编辑控制器:波斯数字显示与setter未被调用问题

解决自定义TextEditingController显示波斯数字、返回英文数字的问题

问题根源

你重写的text setter未被触发,因为TextField在处理用户输入时,直接操作的是controller的value属性,而非调用text setter,导致输入的数字无法转换为波斯数字显示。

解决方案

重写value的setter,在更新值时自动将文本中的英文数字转为波斯数字;同时保留text getter,将显示的波斯数字转回英文数字供外部获取。

1. 定义数字转换扩展方法

如果还未实现数字转换逻辑,先添加以下扩展:

extension StringNumberExtensions on String {
  // 英文数字转波斯数字
  String get toPersianNumbers {
    const englishDigits = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
    const persianDigits = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'];
    String result = this;
    for (int i = 0; i < englishDigits.length; i++) {
      result = result.replaceAll(englishDigits[i], persianDigits[i]);
    }
    return result;
  }

  // 波斯数字转英文数字
  String get toEnglishNumbers {
    const persianDigits = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'];
    const englishDigits = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
    String result = this;
    for (int i = 0; i < persianDigits.length; i++) {
      result = result.replaceAll(persianDigits[i], englishDigits[i]);
    }
    return result;
  }
}

2. 修改自定义TextEditingController

class PersianTextEditingController extends TextEditingController {

  @override
  String get text => value.text.toEnglishNumbers;

  @override
  set value(TextEditingValue newValue) {
    // 将输入文本中的英文数字转为波斯数字
    final persianText = newValue.text.toPersianNumbers;
    // 保持光标和选区位置不变(数字替换长度一致,无需调整)
    super.value = TextEditingValue(
      text: persianText,
      selection: newValue.selection,
      composing: newValue.composing,
    );
  }

  factory PersianTextEditingController({String? text}) =>
      PersianTextEditingController._(text: text);

  PersianTextEditingController._({String? text}) {
    // 初始化时转换初始文本
    super.value = TextEditingValue(
      text: (text ?? '').toPersianNumbers,
      selection: const TextSelection.collapsed(offset: -1),
      composing: TextRange.empty,
    );
  }
}

核心逻辑说明

  • 显示层:每次TextField更新value时,value setter会自动将输入的英文数字转为波斯数字,确保界面显示波斯数字。
  • 数据层:外部调用controller.text时,text getter会将显示的波斯数字转回英文数字,满足业务获取需求。
  • 光标处理:由于数字是一对一替换,文本长度不变,光标和选区位置无需额外调整,输入体验不受影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 10:01:16