TaylorR
TaylorR

Reputation: 4013

Can I format a number before it is rendered in <Text>

I am rendering a <Text> node in Flutter app something like:

We have total ${_summary['bookCount']} books. 

_summary is retrieved via a remote API and bookCount is one of the returned JSON field. It normally is more than 1,000.

If I display the book count like that, it is a plain 1234. I would like to make it be shown as 1,234.

Currently, I have to manually modify that field using some formatter but this is cumbersome.

I am looking for something like:

We have total ${myNumberFormat(_summary['bookCount'])} books. 

grammar, where myNumberFormat is a function.

In my previous programming in PHP and Twig, this can be done with a filter.

Much appreciate your input.

Update

@raju-bitter

This solution is what I know and is absolutely correct. What I am looking for is an inline "filter".

With this solution, a few things I don't like, the most of which is that, I have to split my one liner of text into several few segments: We have {XXX} books, accumulating to {YYY} pages, and {ZZZ} word counts. This sentence will be broken to 7 parts at least so that each number text section can be formatted via a formatter and then wrapped in a surrounding <Text>.

I am trying to see if there are more straightforward ways to do so.

Upvotes: 34

Views: 72803

Answers (6)

Ali Radmanesh
Ali Radmanesh

Reputation: 2536

An update for above answers:

First add intl package into your pubspec.yaml file, just after flutter sdk (like below):

    dependencies:
      flutter:
        sdk: flutter
      intl: ^0.16.0

If you use flutter_localizations, intl must be above of that.

Now you can use NumberFormat class.

Some examples:

print(NumberFormat.currency().format(123456)); // USD123,456.00

print(NumberFormat.currency(locale: 'eu').format(123456)); // 123.456,00 EUR

print(NumberFormat.currency(name: 'EURO').format(123456)); // EURO123,456.00

print(NumberFormat.currency(locale: 'eu', symbol: '?').format(123456)); // 123.456,00 ?

print(NumberFormat.currency(locale: 'eu', decimalDigits: 3).format(123456)); // 123.456,000 EUR

print(NumberFormat.currency(locale: 'eu', customPattern: '\u00a4 #,##.#').format(123456)); // EUR 12.34.56,00

Upvotes: 14

Carlos Cuellar
Carlos Cuellar

Reputation: 89

Using the intl package will limit you to format numbers without decimals. You can make it easy with a function for counting positions and add the thousands separator where it's needed.

String numf(String n) {
  var numArr = n.split('');
  String revStr = "";
  int thousands = 0;
  for (var i = numArr.length - 1; i >= 0; i--) {
    if (numArr[i].toString() == ".") {
      thousands = 0;
    } else {
      thousands++;
    }
    revStr = revStr + numArr[i].toString();
    if (thousands == 3 && i > 0) {
      thousands = 0;
      revStr = revStr + ',';
    }
  }
  return revStr.split('').reversed.join('');
}

Upvotes: 1

raju-bitter
raju-bitter

Reputation: 9006

There is a Dart package for formatting numbers, the Dart intl package. To use the package, add the following line to the Dart dependencies: pubspec.yaml file:

  intl: ^0.17.0

Here's what my dependencies look like with the line:

dependencies:
  flutter:
    sdk: flutter
    intl: ^0.17.0

Click packages get in IntelliJ, or run flutter packages get from the command line.

Make sure your class imports the intl package:

import 'package:intl/intl.dart' as intl;

In your code, you can use NumberFormat class to do the formatting:

  final formatter =  intl.NumberFormat.decimalPattern().format(1234) // formatted number will be: 1,234

Full stateful widget example:

class NumberFormatExample extends StatefulWidget {
  @override
  _NumberFormatExampleState createState() => new _NumberFormatExampleState();
}

class _NumberFormatExampleState extends State<NumberFormatExample> {
  final formatter = intl.NumberFormat.decimalPattern();
  int theValue = 1234;

  @override
  Widget build(BuildContext context) {
    return new Text(formatter.format(theValue));
  }
}
  

Upvotes: 72

CopsOnRoad
CopsOnRoad

Reputation: 268504

Using intl package,

double number = 1234;
String output = NumberFormat.decimalPattern().format(number); // 1,234

Upvotes: 5

Lamina Kehinde Mary
Lamina Kehinde Mary

Reputation: 11

There is a Flutter package that allows you to format text input with predefined patterns. First add the following line to the Dart dependencies: pubspec.yaml file:

    pattern_formatter: ^1.0.2```
then import it in your dart code
    import 'package:pattern_formatter/pattern_formatter.dart';

Example: Thousand group
    TextField(
      keyboardType: TextInputType.number,
      inputFormatters: [
      ThousandsFormatter()
    ],
   )

Decimal Number
    TextField(
     keyboardType: TextInputType.number,
     inputFormatters: [
     ThousandsFormatter(allowFraction: true)
  ],
 )

Card number grouping 

    TextField(
      keyboardType: TextInputType.number,
      inputFormatters: [
      CreditCardFormatter(),
    ],
   )

Date format

    TextField(
      keyboardType: TextInputType.number,
      inputFormatters: [
      DateInputFormatter(),
  ],
)

    

Upvotes: 1

Avijit Nagare
Avijit Nagare

Reputation: 8802

In for loop you can try:

Text('Index ${i}'), //Index 0

Format with operation:

Text('Total: \$${price * quantity}'),  //$20

With Decimal point:

Text('\$${cart.totalAmount.toStringAsFixed(2)}'), //2.34

Upvotes: 3

Related Questions