El problema

El TextEditingController que trae Flutter trata los números como texto plano. Cuando un usuario escribe 1000000 en un campo de precio, ve exactamente eso: un muro ilegible de dígitos. No hay agrupación, ni formato decimal, ni símbolo de moneda. Los desarrolladores acaban escribiendo lógica propia de TextInputFormatter, parseando cadenas a mano y peleándose con errores de posición del cursor cada vez que el formato cambia la longitud del texto.

Los problemas habituales incluyen:

  • Los usuarios leen mal los números grandes sin separadores de miles
  • Campos de moneda que ignoran las convenciones del idioma (posición del símbolo, coma frente a punto)
  • Código de parseo frágil que se rompe cuando el texto formateado contiene caracteres que no son dígitos
  • El cursor saltando a posiciones inesperadas tras cada pulsación

Cómo lo resuelve number_editing_controller

number_editing_controller es un reemplazo directo de TextEditingController. Asígnalo a cualquier TextField y se encarga del formato, el parseo y la gestión del cursor automáticamente.

El usuario ve texto correctamente formateado como $1,234.56 o 1.234,56 €, mientras tu código lee el valor numérico limpio a través de controller.number.

Qué soporta

  • Formato de enteros — agrupa los dígitos con los separadores propios del idioma (1,000,000 en inglés, 1.000.000 en alemán)
  • Formato decimal — dígitos decimales mínimos y máximos configurables
  • Formato de moneda — coloca el símbolo antes o después del número según las reglas del idioma
  • Conciencia de locale — usa patrones de formato ICU, así que 1234.56 en USD se muestra como $1,234.56 en inglés y 1.234,56 $ en alemán
  • Números negativos — flag opcional allowNegative para restringir la entrada a valores positivos
  • Cambios en tiempo de ejecución — cambia idioma, moneda o precisión sobre la marcha sin recrear el controlador
  • Símbolo de moneda externo — muestra el símbolo como decoración prefix/suffix del TextField en lugar de como texto en línea

Casos de uso reales

Checkout de comercio electrónico

Un formulario de pago necesita aceptar importes en varias monedas. Con number_editing_controller creas un único controlador de moneda y cambias currencyName cuando el usuario elige otra. El campo se reformatea al instante, sin necesidad de reconstruir nada.

Apps financieras multilingües

Una app bancaria que atiende a usuarios en EE. UU., Alemania y Japón necesita las convenciones de cada idioma: $1,234.56 frente a 1.234,56 € frente a ¥1,500. El controlador gestiona todo esto desde un único parámetro locale.

Campos de inventario y cantidades

Las apps de almacén manejan cantidades enteras grandes. El controlador de enteros convierte 1000000 en 1,000,000, lo que hace fáciles de detectar los errores de introducción de datos.

Cuadros de mando analíticos

Los controladores decimales con precisión configurable te permiten dar formato a métricas —porcentajes con 2 dígitos, mediciones científicas con 4— manteniendo disponible el valor num en bruto para los cálculos.

Ejemplos de formato por idioma

LocaleTipoValor en brutoMostrado
enMoneda (USD)1234.56$1,234.56
deMoneda (EUR)1234.561.234,56 €
frMoneda (EUR)1234.561 234,56 €
jaMoneda (JPY)1500¥1,500
ruMoneda (RUB)500500 ₽
enEntero12345671,234,567
deDecimal (máx. 2)1234.891.234,89

Cómo empezar

Instala el paquete:

flutter pub add number_editing_controller

Requiere Flutter 3.19+ y Dart 3.3+.

Después crea un controlador y asígnalo a tu TextField:

final controller = NumberEditingTextController.currency(
  currencyName: 'USD',
  locale: 'en',
);

TextField(
  controller: controller,
  keyboardType: TextInputType.numberWithOptions(decimal: true, signed: true),
)

// Read the numeric value at any time
final amount = controller.number; // e.g. 1234.56

Hay tres tipos de controlador disponibles: .integer(), .decimal() y .currency(). Todas las opciones —idioma, separadores, moneda, precisión— pueden cambiarse en tiempo de ejecución sin recrear el controlador.

Tienes un ejemplo completo y funcional, con selector de moneda, cambio de idioma y colocación externa del símbolo, en el directorio de ejemplos.

Sí, pero JavaScript representa todos los números como flotantes de 64 bits, así que los enteros por encima de 2^53 - 1 (unos 9 billones largos) pierden precisión en silencio. En plataformas nativas, los enteros de 64 bits están totalmente soportados.
Sí. Todas las opciones de formato son mutables en tiempo de ejecución. Cambiar el idioma, el nombre de la moneda, los separadores o la precisión reformatea de inmediato el texto mostrado sin recrear el controlador.
Todavía no. La librería usa tamaños de grupo uniformes derivados de los patrones de locale de ICU (normalmente grupos de 3). Los sistemas de agrupación de anchura variable, como la numeración india, no están soportados.
Pon showCurrencySymbol a false y usa las propiedades resolvedCurrencySymbol y currencySymbolPosition para colocar el símbolo como decoración prefix o suffix del TextField.
La precisión decimal está limitada a 20 dígitos decimales (el límite de toStringAsFixed de Dart). Las entradas extremadamente largas pueden degradar el rendimiento del formato, pero los valores financieros y de negocio habituales se manejan sin problemas.