Как отобразить формат валюты с разделителями в калькуляторе EMI ​​во Flutter

Я создаю калькулятор электромагнитных помех во флаттере, но мои результаты отображаются, например, как 1250568.00, но я хочу, чтобы он отображался как N$ 1,250,568.00

я пробовал пакет intl, но получаю сообщение об ошибке Text(f.format(_tiResults)),, как объяснялось, как его реализовать. также пробовал пакет MoneyMask безрезультатно.

import 'package:homenet/pages/home_page.dart';
import 'dart:math';

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List _durationTypes = ['Month(s)', 'Year(s)'];
  String _durationType = "Year(s)";
  String _miResult = "";
  String _tiResult = "";
  String _tcResult = "";
  bool _switchValue = true;

  final TextEditingController _principalAmount = TextEditingController();
  final TextEditingController _interestRate = TextEditingController();
  final TextEditingController _loanDuration = TextEditingController();

  _onClear(){
    setState(() {
      _principalAmount.text = "";
      _interestRate.text = "";
      _loanDuration.text = "";
      _miResult = "";
      _tiResult = "";
      _tcResult = "";
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      resizeToAvoidBottomPadding: false,
      appBar: AppBar(
        backgroundColor: new Color(0xFFFA983A),
        title: InkWell(
          onTap: (){
            Navigator.push(context,
              MaterialPageRoute(builder: (context) => new HomePage()));},
          child: Image.asset(
            'assets/images/logo_white.png',
            fit: BoxFit.cover,
          ),
        ),
        elevation: 0.0,
        centerTitle: true,
        actions: <Widget>[
          new IconButton(
            icon: new Icon(Icons.cancel, size: 30,),
            onPressed: () {
              _onClear();
            },
          ),
        ],
      ),
      body: Center(
        child: Container(
          margin: EdgeInsets.all(24),
          child: Column(
            children: <Widget>[
              Container(
                child: TextField(
                  cursorColor: Color(0xFFFA983A),
                  controller: _principalAmount,
                  decoration:
                      InputDecoration(
                  icon: Icon(Icons.monetization_on),
                  border: OutlineInputBorder(
                      borderRadius: BorderRadius.circular(25),
                  gapPadding: 5),
                  labelText: "Enter Principal Amount"),

                  keyboardType: TextInputType.numberWithOptions(),
                ),
              ),
              SizedBox(
                height: 12,
              ),
              Container(
                child: TextField(
                  cursorColor: Color(0xFFFA983A),
                  controller: _interestRate,
                  decoration:
                      InputDecoration(
                          icon: Icon(Icons.show_chart),
                          border: OutlineInputBorder(
                              borderRadius: BorderRadius.circular(25),
                              gapPadding: 5),
                          labelText: "Interest Rate per Annum %"),
                  keyboardType: TextInputType.numberWithOptions(),
                ),
              ),
              SizedBox(
                height: 12,
              ),
              Row(
                children: <Widget>[
                  Flexible(
                    flex: 3,
                    child: Container(
                      child: TextField(
                        cursorColor: Color(0xFFFA983A),
                        controller: _loanDuration,
                        decoration: InputDecoration(
                            icon: Icon(Icons.date_range),
                            border: OutlineInputBorder(
                                borderRadius: BorderRadius.circular(25),
                                gapPadding: 5),
                            labelText: "Loan Duration"),
                        keyboardType: TextInputType.numberWithOptions(),
                      ),
                    ),
                  ),
//                  TODO: ========= SWITCH ================
                  Flexible(
                    flex: 1,
                    child: Column(
                      children: <Widget>[
                        Text(
                          _durationType,
                          style: TextStyle(
                            fontWeight: FontWeight.bold,
                          ),
                        ),
                        Switch(
                            activeColor: Color(0xFFFA983A),
                            value: _switchValue,
                            onChanged: (bool value) {
                              print(value);

                              if (value) {
                                _durationType = _durationTypes[1];
                              } else {
                                _durationType = _durationTypes[0];
                              }

                              setState(() {
                                _switchValue = value;
                              });
                            }),
                      ],
                    ),
                  ),
                ],
              ),
              SizedBox(
                height: 12,
              ),
//              TODO: ============== Button ============
              Flexible(
                child: FlatButton(
                  padding: EdgeInsets.fromLTRB(48, 8, 48, 8),
                  onPressed: _handleCalculation,
                  child: Text(
                    "CALCULATE",
                    style: TextStyle(color: Colors.white),
                  ),
                  color: Color(0xFFFA983A),
                ),
              ),
              SizedBox(
                height: 12,
              ),
//              TODO: Results Widget =====================================
              monthlyInstalmentsResult(_miResult),
              SizedBox(
                height: 12,
              ),
              totalInterestResult(_tiResult),
              SizedBox(
                height: 12,
              ),
              totalCostResult(_tcResult),
              SizedBox(
                height: 12,
              ),
              Container(
                child: Text(
                  "Disclaimer* This is just an approximate amount"
                  "and in no way reflect the exact figures, please consult your bank.",
                  style: TextStyle(
                    color: Colors.grey,
                    fontSize: 10,
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  void _handleCalculation() {
//    TODO: Amortization
    //    TODO: A = Payment amount per period
    //    TODO: P = Initial Principal (Loan Amount)
    //    TODO: r = interest Rate
    //    TODO: n = Total number of payments

    double A = 0.0;
    double I = 0.0;
    double T = 0.0;
    double P = double.parse(_principalAmount.text);
    double r = double.parse(_interestRate.text) / 12 / 100;
    int n = _durationType == "Year(s)"
        ? int.parse(_loanDuration.text) * 12
        : int.parse(_loanDuration.text);

    A = (P * r * pow((1 + r), n) / (pow((1 + r), n) - 1));
    T = (A * n);
    I = (T - P);

    _miResult = A.toStringAsFixed(2);
    setState(() {});
    _tiResult = I.toStringAsFixed(2);
    setState(() {});
    _tcResult = T.toStringAsFixed(2);
    setState(() {});
  }

  Widget monthlyInstalmentsResult(miResults) {

//    var f = new NumberFormat("#,###,###.0#");
//    var f = new NumberFormat("###.0#", "en_US");
    bool canShow = false;
    String _miResults = miResults;

    if (_miResults.length > 0) {
      canShow = true;
    }
    return Container(

        child: canShow
            ? Row(
                children: <Widget>[
                  Text(
                    "Monthly Instalments: ",
                    style: TextStyle(
                      color: Colors.grey,
                      fontSize: 18,
                    ),
                  ),
                  Text(
                    "N\$ ",
                    style: TextStyle(
                      color: Color(0xFFFA983A),
                      fontSize: 24,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                  Text(
                    _miResult,
                    style: TextStyle(
                      color: Color(0xFFFA983A),
                      fontSize: 24,
                      fontWeight: FontWeight.bold,
                    ),
                  )
                ],
              )
            : Row());
  }

  Widget totalInterestResult(tiResults) {
    bool canShow = false;
    String _miResults = tiResults;

    if (_miResults.length > 0) {
      canShow = true;
    }
    return Container(
        child: canShow
            ? Row(
                children: <Widget>[
                  Text(
                    "Total Interest: ",
                    style: TextStyle(
                      color: Colors.grey,
                      fontSize: 18,
                    ),
                  ),
                  Text(
                    "N\$ ",
                    style: TextStyle(
                      color: Color(0xFFFA983A),
                      fontSize: 24,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                  Text(
                    _tiResult,
                    style: TextStyle(
                      color: Color(0xFFFA983A),
                      fontSize: 24,
                      fontWeight: FontWeight.bold,
                    ),
                  )
                ],
              )
            : Row());
  }

  Widget totalCostResult(tcResults) {
    bool canShow = false;
    String _miResults = tcResults;

    if (_miResults.length > 0) {
      canShow = true;
    }
    return Container(
        child: canShow
            ? Row(
                children: <Widget>[
                  Text(
                    "Total Cost: ",
                    style: TextStyle(
                      color: Colors.grey,
                      fontSize: 18,
                    ),
                  ),
                  Text(
                    "N\$ ",
                    style: TextStyle(
                      color: Color(0xFFFA983A),
                      fontSize: 24,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                  Text(
                    _tcResult,
                    style: TextStyle(
                      color: Color(0xFFFA983A),
                      fontSize: 24,
                      fontWeight: FontWeight.bold,
                    ),
                  )
                ],
              )
            : Row());
  }
}

Код воспроизводится точно так же, как он есть в моем приложении.... Я хочу, чтобы результаты (miResults, tiResults и tcResults) отображались в финансовом/валютном формате. Спасибо.

Не могли бы вы поделиться минимальным воспроизведением вашего кода? Нам было бы проще повторить и найти решение для вас.

Hugo Passos 21.05.2019 15:43

Приведенный выше код полностью воспроизводим. Редкая вещь, которую можно увидеть здесь, на SO.

Mazin Ibrahim 21.05.2019 15:51

Что не работает? Это, кажется, делает это. NumberFormat format = NumberFormat('#,###,###.00'); print('N\$${format.format(1250568.00)}');

Richard Heap 21.05.2019 15:51

Это @HugoPassos...

Griffin Fisch 21.05.2019 18:26

Да, @MazinIbrahim, мне так проще, чем публиковать код несколько раз...

Griffin Fisch 21.05.2019 18:26

@RichardHeap Я сделал, но выдает ошибку Class 'String' has no instance getter 'isNegative'., когда я это делаю ('N\$${format.format(_ _miResult)}')

Griffin Fisch 21.05.2019 18:31

@GriffinFisch Я действительно ценю ваш способ составления вопросов, это упрощает ответы на них, чем на другие вопросы с урезанным кодом. Мой ответ был фактически направлен на первый комментарий. И, кстати, придерживайтесь этого стиля, и вы всегда найдете быстрый и хороший ответ на свои вопросы.

Mazin Ibrahim 21.05.2019 18:38

@MazinIbrahim Нет проблем ... Я все еще новичок в этом, поэтому я должен быть как можно более ясным.

Griffin Fisch 21.05.2019 18:53

@GriffinFisch Вы не можете использовать средство форматирования чисел для строки - вам нужно использовать его для числа - см. Ответ

Richard Heap 21.05.2019 18:53
0
9
3 708
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Попробуй это:

  void _handleCalculation() {
    //    TODO: Amortization
    //    TODO: A = Payment amount per period
    //    TODO: P = Initial Principal (Loan Amount)
    //    TODO: r = interest Rate
    //    TODO: n = Total number of payments

    double A = 0.0;
    double I = 0.0;
    double T = 0.0;
    double P = double.parse(_principalAmount.text);
    double r = double.parse(_interestRate.text) / 12 / 100;
    int n = _durationType == "Year(s)"
        ? int.parse(_loanDuration.text) * 12
        : int.parse(_loanDuration.text);

    A = (P * r * pow((1 + r), n) / (pow((1 + r), n) - 1));
    T = (A * n);
    I = (T - P);

    NumberFormat format = NumberFormat('#,###,###.00');
    setState(() {
      _miResult = format.format(A);
      _tiResult = format.format(I);
      _tcResult = format.format(T);
    });
  }

Я все еще получаю эту ошибку Another exception was thrown: NoSuchMethodError: Class 'String' has no instance getter 'isNegative'., если я помещаю его в setState или говорю, что «A», «I» и «T» не определены?

Griffin Fisch 21.05.2019 18:55

A, I и T определены, всего несколькими строками выше... double A = 0.0; double I = 0.0; double T = 0.0; - можете ли вы обновить вопрос, показывающий новую версию, в которой говорится, что A не определено?

Richard Heap 21.05.2019 19:00

наконец-то получил это правильно после того, как передвинул его тысячу раз. Спасибо, наконец, получилось, поместив свой код внизу моего кода _handleCalculation(). спасибо... очень признателен.

Griffin Fisch 21.05.2019 19:18

Рад слышать. Не забудьте принять ответ, если он полезен.

Richard Heap 21.05.2019 19:22

у вас, возможно, есть какие-либо идеи по этому поводу, если вы не возражаете? stackoverflow.com/questions/56221889/…

Griffin Fisch 22.05.2019 23:46

Другие вопросы по теме