'Flutter TextField with currency format
There's is some way to do a money format in a TextField to when the user going typing the value it going already formatting in real time?
Like in the above image, while the user is typing the format goes updating the value formatted already.
[UPDATE]
I just found this library that makes it works like a charm: https://pub.dartlang.org/packages/flutter_masked_text
Solution 1:[1]
An easy solution to set a custom money mask, is to use the flutter_masked_text package:
1 - First of all, you need add this packege to your package's pubspec.yaml file:
dependencies:
flutter_masked_text: ^0.7.0
2 - After that, install the package using the command line (as below), or use a graphic interface for it, if you are using the IntelliJ IDEA just click in the button "Packages get".
flutter packages get
3 - Now in your Dart code, import it...
import 'package:flutter_masked_text/flutter_masked_text.dart';
4 - Lastly, change your TextField controller code from "TextEditingController" to "MoneyMaskedTextController":
//final lowPrice = TextEditingController(); //before
final lowPrice = MoneyMaskedTextController(decimalSeparator: '.', thousandSeparator: ','); //after
Solution 2:[2]
[THIS CODE DOESN'T WORKS FOR ALL CASES]
I just got it working this way, sharing in case someone needs too:
TextField
TextFormField(
//validator: ,
controller: controllerValor,
inputFormatters: [
WhitelistingTextInputFormatter.digitsOnly,
// Fit the validating format.
//fazer o formater para dinheiro
CurrencyInputFormatter()
],
keyboardType: TextInputType.number, ...
TextInputFormatter
class CurrencyInputFormatter extends TextInputFormatter {
TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) {
if(newValue.selection.baseOffset == 0){
print(true);
return newValue;
}
double value = double.parse(newValue.text);
final formatter = NumberFormat.simpleCurrency(locale: "pt_Br");
String newText = formatter.format(value/100);
return newValue.copyWith(
text: newText,
selection: new TextSelection.collapsed(offset: newText.length));
}
}
This is the result of the code:
Solution 3:[3]
Use intl
package. Full code:
import 'package:intl/intl.dart';
class _HomePageState extends State<HomePage> {
final _controller = TextEditingController();
static const _locale = 'en';
String _formatNumber(String s) => NumberFormat.decimalPattern(_locale).format(int.parse(s));
String get _currency => NumberFormat.compactSimpleCurrency(locale: _locale).currencySymbol;
@override
Widget build(BuildContext context) {
return Scaffold(
body: TextField(
controller: _controller,
decoration: InputDecoration(prefixText: _currency),
keyboardType: TextInputType.number,
onChanged: (string) {
string = '${_formatNumber(string.replaceAll(',', ''))}';
_controller.value = TextEditingValue(
text: string,
selection: TextSelection.collapsed(offset: string.length),
);
},
),
);
}
}
Solution 4:[4]
This library works perfect for me:
https://pub.dev/packages/currency_text_input_formatter
...
inputFormatters: [
CurrencyTextInputFormatter(
decimalDigits: 0,
locale: 'ru',
)
]
...
Solution 5:[5]
Updated the code from @AndréLuis to limit the number of digits (maxDigits), thanks for sharing.
import 'package:flutter/services.dart';
import 'package:intl/intl.dart';
class CurrencyPtBrInputFormatter extends TextInputFormatter {
CurrencyPtBrInputFormatter({this.maxDigits});
final int maxDigits;
TextEditingValue formatEditUpdate(
TextEditingValue oldValue, TextEditingValue newValue) {
if (newValue.selection.baseOffset == 0) {
return newValue;
}
if (maxDigits != null && newValue.selection.baseOffset > maxDigits) {
return oldValue;
}
double value = double.parse(newValue.text);
final formatter = new NumberFormat("#,##0.00", "pt_BR");
String newText = "R\$ " + formatter.format(value / 100);
return newValue.copyWith(
text: newText,
selection: new TextSelection.collapsed(offset: newText.length));
}
}
Use the code bellow for the TextFormField, I'm also parsing the value to double, removing the non-digit chars using RegExp.
TextFormField(
maxLines: 1,
keyboardType: TextInputType.number,
inputFormatters: [
WhitelistingTextInputFormatter.digitsOnly,
CurrencyPtBrInputFormatter(maxDigits: 8),
],
onSaved: (value) {
String _onlyDigits = value.replaceAll(RegExp('[^0-9]'), "");
double _doubleValue = double.parse(_onlyDigits) / 100;
return _valor = _doubleValue;
},
);
Solution 6:[6]
To make a cleaner code the umasked value could be included in the Formatter class as a method. So when the value got changed you will be able to call it and simplifying the code.
Widget build(BuildContext context) {
var maskFormatter = new CurrencyPtBrFormatter(maxDigits: 12);
return Scaffold(
body: SingleChildScrollView(
controller: _scrollController,
child: Column(
children: <Widget>[
TextField(
keyboardType: TextInputType.number,
inputFormatters: [
WhitelistingTextInputFormatter.digitsOnly,
maskFormatter,
],
controller: _yourController,
onChanged: (value) {
print(maskFormatter.getUnmaskedDouble()); // here the umasked value
},
onEditingComplete: () {
mudarFocoCampo(context, _estoqueFocus, _codigoFocus);
},
)
],
)));
}
Here the complete formatter with umasked method.
import 'package:flutter/services.dart';
import 'package:intl/intl.dart';
class CurrencyPtBrFormatter extends TextInputFormatter {
CurrencyPtBrFormatter({this.maxDigits});
final int maxDigits;
double _uMaskValue;
TextEditingValue formatEditUpdate(
TextEditingValue oldValue, TextEditingValue newValue) {
if (newValue.selection.baseOffset == 0) {
return newValue;
}
if (maxDigits != null && newValue.selection.baseOffset > maxDigits) {
return oldValue;
}
double value = double.parse(newValue.text);
final formatter = new NumberFormat("#,##0.00", "pt_BR");
String newText = "R\$ " + formatter.format(value / 100);
//setting the umasked value
_uMaskValue = value / 100;
return newValue.copyWith(
text: newText,
selection: new TextSelection.collapsed(offset: newText.length));
}
//here the method
double getUnmaskedDouble() {
return _uMaskValue;
}
}
Solution 7:[7]
Using pattern_formatter package,
TextField(
keyboardType: TextInputType.number,
inputFormatters: [
ThousandsFormatter()
],
)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | GPaiva |
Solution 3 | |
Solution 4 | Ilya Iksent |
Solution 5 | daniloxvalle |
Solution 6 | |
Solution 7 | Shlomi |