Je veux seulement deux chiffres après la virgule décimale dans l'entrée flutter. L'utilisateur ne peut pas ajouter plus de deux chiffres après la virgule décimale.
9 Réponses :
Voici! J'espère que cela aide :)
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'dart:math' as math; void main() { runApp(new MaterialApp(home: new MyApp())); } class MyApp extends StatefulWidget { @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Flutter"), ), body: Form( child: ListView( children: <Widget>[ TextFormField( inputFormatters: [DecimalTextInputFormatter(decimalRange: 2)], keyboardType: TextInputType.numberWithOptions(decimal: true), ) ], ), ), ); } } class DecimalTextInputFormatter extends TextInputFormatter { DecimalTextInputFormatter({this.decimalRange}) : assert(decimalRange == null || decimalRange > 0); final int decimalRange; @override TextEditingValue formatEditUpdate( TextEditingValue oldValue, // unused. TextEditingValue newValue, ) { TextSelection newSelection = newValue.selection; String truncated = newValue.text; if (decimalRange != null) { String value = newValue.text; if (value.contains(".") && value.substring(value.indexOf(".") + 1).length > decimalRange) { truncated = oldValue.text; newSelection = oldValue.selection; } else if (value == ".") { truncated = "0."; newSelection = newValue.selection.copyWith( baseOffset: math.min(truncated.length, truncated.length + 1), extentOffset: math.min(truncated.length, truncated.length + 1), ); } return TextEditingValue( text: truncated, selection: newSelection, composing: TextRange.empty, ); } return newValue; } }
@AjayKumar le code 'math.min (truncated.length, truncated.length + 1)' semble assez redondant.
Le problème avec ceci est de forcer un "." ne prend pas en charge les paramètres régionaux qui intervertissent les points et les virgules.
@AjayKumar Merci, a travaillé pour moi. Sur certains claviers, il est nécessaire de cliquer sur le point pour ajouter un signe moins. Dans cette classe, vous pouvez entrer moins après avoir entré toutes les valeurs. J'ajouterai si je vérifie cela. Merci encore.
Si l'utilisateur ajoute plus de nombres après les décimales, la suppression ne fonctionne pas avant d'atteindre les deux premiers nombres.
J'ai étendu les fonctionnalités ... J'espère que vous pourrez le trouver utile. Dites-moi si vous pouvez vous améliorer encore plus s'il vous plaît.
import 'package:flutter/services.dart'; import 'dart:math' as math; class DecimalTextInputFormatter extends TextInputFormatter { DecimalTextInputFormatter({this.decimalRange, this.activatedNegativeValues}) : assert(decimalRange == null || decimalRange >= 0, 'DecimalTextInputFormatter declaretion error'); final int decimalRange; final bool activatedNegativeValues; @override TextEditingValue formatEditUpdate( TextEditingValue oldValue, // unused. TextEditingValue newValue, ) { TextSelection newSelection = newValue.selection; String truncated = newValue.text; if (newValue.text.contains(' ')) { return oldValue; } if (newValue.text.isEmpty) { return newValue; } else if (double.tryParse(newValue.text) == null && !(newValue.text.length == 1 && (activatedNegativeValues == true || activatedNegativeValues == null) && newValue.text == '-')) { return oldValue; } if (activatedNegativeValues == false && double.tryParse(newValue.text) < 0) { return oldValue; } if (decimalRange != null) { String value = newValue.text; if (decimalRange == 0 && value.contains(".")) { truncated = oldValue.text; newSelection = oldValue.selection; } if (value.contains(".") && value.substring(value.indexOf(".") + 1).length > decimalRange) { truncated = oldValue.text; newSelection = oldValue.selection; } else if (value == ".") { truncated = "0."; newSelection = newValue.selection.copyWith( baseOffset: math.min(truncated.length, truncated.length + 1), extentOffset: math.min(truncated.length, truncated.length + 1), ); } return TextEditingValue( text: truncated, selection: newSelection, composing: TextRange.empty, ); } return newValue; } }
les solutions ici sont plutôt bonnes. Je pense que ce serait encore mieux si la virgule était incluse lors du formatage par milliers.
Bonjour Monsieur! Il est possible d'ajouter un format numérique à votre code avec decimalRange max 2? Je veux réaliser ceci: "100,25" "1 000,25" "10 000,25"
Une version plus courte de DecimalTextInputFormatter utilisant Regexp:
class DecimalTextInputFormatter extends TextInputFormatter { DecimalTextInputFormatter({int decimalRange, bool activatedNegativeValues}) : assert(decimalRange == null || decimalRange >= 0, 'DecimalTextInputFormatter declaretion error') { String dp = (decimalRange != null && decimalRange > 0) ? "([.][0-9]{0,$decimalRange}){0,1}" : ""; String num = "[0-9]*$dp"; if(activatedNegativeValues) { _exp = new RegExp("^((((-){0,1})|((-){0,1}[0-9]$num))){0,1}\$"); } else { _exp = new RegExp("^($num){0,1}\$"); } } RegExp _exp; @override TextEditingValue formatEditUpdate( TextEditingValue oldValue, TextEditingValue newValue, ) { if(_exp.hasMatch(newValue.text)){ return newValue; } return oldValue; } }
Merci, ce code ignore également les lettres et les symboles, ne laissant que des chiffres et un point.
La réponse de @AjayKumar permet de limiter la saisie de texte aux décimales requises, mais mon exigence était d'éviter un autre caractère du clavier à l'exception du nombre et d'un point.J'ai donc mis à jour la réponse ci-dessus de @ AjayKumar
import 'package:flutter/services.dart'; import 'dart:math' as math; class DecimalTextInputFormatter extends TextInputFormatter { DecimalTextInputFormatter({this.decimalRange}) : assert(decimalRange == null || decimalRange > 0); final int decimalRange; @override TextEditingValue formatEditUpdate( TextEditingValue oldValue, // unused. TextEditingValue newValue, ) { TextSelection newSelection = newValue.selection; String truncated = newValue.text; if (decimalRange != null) { String value = newValue.text; if (value.contains(',') || value.contains('-') || value.contains(' ') || value.contains('..')) { truncated = oldValue.text; newSelection = oldValue.selection; } else if (value.contains(".") && value.substring(value.indexOf(".") + 1).length > decimalRange) { truncated = oldValue.text; newSelection = oldValue.selection; } else if (value == ".") { truncated = "0."; newSelection = newValue.selection.copyWith( baseOffset: math.min(truncated.length, truncated.length + 1), extentOffset: math.min(truncated.length, truncated.length + 1), ); } return TextEditingValue( text: truncated, selection: newSelection, composing: TextRange.empty, ); } return newValue;
}}
Peut-être un peu en retard pour vous, mais j'ai aussi amélioré un peu:
.
J'espère que cela aide ;)
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; class NumberFormField extends StatelessWidget { final InputDecoration decoration; final TextEditingController controller; final int decimalRange; const NumberFormField({Key key, this.decoration, this.controller, this.decimalRange}) :super(key: key); @override Widget build(BuildContext context) { return TextFormField( decoration: this.decoration, controller: this.controller, keyboardType: TextInputType.numberWithOptions(decimal: true), inputFormatters: [ WhitelistingTextInputFormatter(RegExp(r'[\d+\-\.]')), NumberTextInputFormatter(decimalRange: this.decimalRange), ], ); } }
et (n'oubliez pas d'importer la classe précédente)
import 'package:flutter/services.dart'; class NumberTextInputFormatter extends TextInputFormatter { NumberTextInputFormatter({this.decimalRange}) : assert(decimalRange == null || decimalRange > 0); final int decimalRange; @override TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) { TextEditingValue _newValue = this.sanitize(newValue); String text = _newValue.text; if (decimalRange == null) { return _newValue; } if (text == '.') { return TextEditingValue( text: '0.', selection: _newValue.selection.copyWith(baseOffset: 2, extentOffset: 2), composing: TextRange.empty, ); } return this.isValid(text) ? _newValue : oldValue; } bool isValid(String text) { int dots = '.'.allMatches(text).length; if (dots == 0) { return true; } if (dots > 1) { return false; } return text.substring(text.indexOf('.') + 1).length <= decimalRange; } TextEditingValue sanitize(TextEditingValue value) { if (false == value.text.contains('-')) { return value; } String text = '-' + value.text.replaceAll('-', ''); return TextEditingValue(text: text, selection: value.selection, composing: TextRange.empty); } }
Et en évitant les zéros inutiles ... Veuillez déboguer ce code.
import 'dart:math' as math; import 'package:flutter/services.dart'; class DecimalTextInputFormatter extends TextInputFormatter { DecimalTextInputFormatter({this.decimalRange, this.activatedNegativeValues}) : assert(decimalRange == null || decimalRange >= 0, 'DecimalTextInputFormatter declaretion error'); final int decimalRange; final bool activatedNegativeValues; @override TextEditingValue formatEditUpdate( TextEditingValue oldValue, // unused. TextEditingValue newValue, ) { TextSelection newSelection = newValue.selection; String truncated = newValue.text; if (newValue.text.contains(' ')) { return oldValue; } if (newValue.text.isEmpty) { return newValue; } else if (double.tryParse(newValue.text) == null && !(newValue.text.length == 1 && (activatedNegativeValues == true || activatedNegativeValues == null) && newValue.text == '-')) { return oldValue; } if (activatedNegativeValues == false && double.tryParse(newValue.text) < 0) { return oldValue; } if ((double.tryParse(oldValue.text) == 0 && !newValue.text.contains('.'))) { if (newValue.text.length >= oldValue.text.length) { return oldValue; } } if (decimalRange != null) { String value = newValue.text; if (decimalRange == 0 && value.contains(".")) { truncated = oldValue.text; newSelection = oldValue.selection; } if (value.contains(".") && value.substring(value.indexOf(".") + 1).length > decimalRange) { truncated = oldValue.text; newSelection = oldValue.selection; } else if (value == ".") { truncated = "0."; newSelection = newValue.selection.copyWith( baseOffset: math.min(truncated.length, truncated.length + 1), extentOffset: math.min(truncated.length, truncated.length + 1), ); } return TextEditingValue( text: truncated, selection: newSelection, composing: TextRange.empty, ); } return newValue; } }
Voici une solution qui fonctionne pour moi
TextFormField( inputFormatters: [ WhitelistingTextInputFormatter(RegExp(r'^(\d+)?\.?\d{0,2}')), ], )
Si vous souhaitez autoriser une entrée comme (.21) ou (.25)
Voici une solution-
TextFormField( inputFormatters: [ WhitelistingTextInputFormatter(RegExp(r'^\d+\.?\d{0,2}')), ], )
Votre solution permet à un utilisateur de saisir des points supplémentaires dans la partie entière
C'est peut-être une solution plus simple
inputFormatters: [ FilteringTextInputFormatter.allow(RegExp(r'(^\d*\.?\d{0,2})')) ]
pouvez-vous spécifier ce qui est mieux par rapport à l'autre réponse qui utilise l'expression régulière?
TextFormField( keyboardType: TextInputType.numberWithOptions(decimal: true), inputFormatters: [ FilteringTextInputFormatter.allow(RegExp(r'^\d+\.?\d{0,2}')), ], ),
Vous pouvez utiliser
TextEditingController
pour écouter les entrées et y gérer votre logique.Il n'y a donc aucune possibilité de format d'entrée. Par exemple, inputFormatters: (keyboardType == TextInputType.number)? [WhitelistingTextInputFormatter.digitsOnly]: [],
Pour autant que je puisse dire, non, ils ne vous aideront pas, ils ne peuvent vous donner que des options pour choisir un type de clavier spécifique.
Merci beaucoup, je ne sais pas pourquoi cette question a obtenu -2 points.
Probablement parce que vous n'avez montré aucun code que vous avez essayé et que personne n'écrira une solution pour vous à partir de zéro.
Vous devriez mettre à jour la réponse, j'en ai trouvé une plus simple.