Форма в флаттере выдает мне случайную ошибку всякий раз, когда я пытаюсь проверить - PullRequest
0 голосов
/ 07 марта 2020

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

════════ Exception caught by widgets library ═══════════════════════════════════
The following NoSuchMethodError was thrown building FoodManualInput(dirty, dependencies: [MediaQuery], state: _FoodManualInputState#a02e9):
The getter 'length' was called on null.
Receiver: null
Tried calling: length

User-created ancestor of the error-causing widget was
    MaterialApp 
lib\main.dart:72
When the exception was thrown, this was the stack
#0      Object.noSuchMethod  (dart:core-patch/object_patch.dart:51:5)
#1      double._parse  (dart:core-patch/double_patch.dart:95:19)

Вот исходный код страницы: (Я удалил содержимое виджета Форма, потому что не смогу опубликуйте этот вопрос, если я этого не сделал)

class _FoodManualInputState extends State<FoodManualInput> {
  final GlobalKey<FormState> _manualInputKey = GlobalKey<FormState>();
  String _foodTypeInput, _noOfFood;

  bool showComputation = false;
  String _fname;
  var _servSize,
      _caloriesSize,
      _carbServSz,
      _sugarServSz,
      _fatServSz,
      _proteinServSz,
      _estServing;

  String numberValidator(String value) {
    if (value == null) {
      return null;
    }
    final n = num.tryParse(value);
    if (n == null) {
      return '"$value" is not a valid number';
    }
    return null;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      resizeToAvoidBottomInset: false,
      body: Container(
        child: Column(
          children: <Widget>[
            SizedBox(height: 20),
            //manual appbar
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Expanded(
                  child: Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: Text(
                      "Add Food (Manual Input)",
                      textAlign: TextAlign.left,
                      style: TextStyle(
                        fontFamily: FintnessAppTheme.fontName,
                        fontWeight: FontWeight.w700,
                        fontSize: 16,
                        letterSpacing: 1.2,
                        color: FintnessAppTheme.darkerText,
                      ),
                    ),
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.only(
                    left: 8,
                  ),
                  child: Row(
                    children: <Widget>[],
                  ),
                ),
                SizedBox(
                    height: 38,
                    width: 38,
                    child: IconButton(
                      onPressed: () {
                        Navigator.pop(context);
                      },
                      icon: Icon(Icons.close),
                      color: FintnessAppTheme.grey,
                      highlightColor: Colors.transparent,
                    )),
              ],
            ),

            Padding(
              padding: const EdgeInsets.all(12.0),
              child: Text(
                'If you\'re eating more than one item, kindly just add the nutrients in grams per field in the form. For example: i\'ll eat Frosties and Bread, I will add the carbs in Frosties, and in the Bread outside the application and input it in the respective formfield.',
                textAlign: TextAlign.justify,
                style: TextStyle(
                  fontFamily: FintnessAppTheme.fontName,
                  fontSize: 13,
                  letterSpacing: 1.2,
                  color: FintnessAppTheme.darkerText,
                ),
              ),
            ),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: Container(
                height: 460,
                child: ListView(
                  children: <Widget>[
                    Center(
                      child: Container(
                        width: 200,
                        child: DropdownButton<String>(
                          hint: Text(
                            'Choose a meal type',
                            textAlign: TextAlign.center,
                          ),
                          items: <String>[
                            'Snack',
                            'Breakfast',
                            'Lunch',
                            'Dinner'
                          ].map((String value) {
                            return new DropdownMenuItem<String>(
                              value: value,
                              child: Text(value),
                            );
                          }).toList(),
                          value: _foodTypeInput,
                          onChanged: (newValue) {
                            setState(() {
                              _foodTypeInput = newValue;
                            });
                          },
                        ),
                      ),
                    ),
                    SizedBox(height: 20),
                    Center(
                      child: Container(
                        width: 370,
                        child: DropdownButton<String>(
                          hint: Text(
                              'Choose a number of foods to manually compute'),
                          items:
                              <String>['1', '2', '3', '4'].map((String value) {
                            return new DropdownMenuItem<String>(
                              value: value,
                              child: Text(value),
                            );
                          }).toList(),
                          value: _noOfFood,
                          onChanged: (newValue) {
                            setState(() {
                              _noOfFood = newValue;
                            });
                          },
                        ),
                      ),
                    ),
                    _foodTypeInput == null || _noOfFood == null
                        ? SizedBox()
                        : Form(RaisedButton(
                                    onPressed: () {
                                      doAction();
                                      setState(() {
                                        showComputation = true;
                                      });
                                    },
                                    child: Text('Compute'),
                                    color: Colors.pink[200],
                                  ),
                                )
                              ],
                            ),
                          ),
                  ],
                ),
              ),
            ),
            Divider(
              color: Colors.indigo,
              thickness: 2,
            ),
            showComputation == false
                ? SizedBox(
                    child: Text('showComputation val: $showComputation'),
                  )
                : Container(
                    child: Column(
                      children: <Widget>[
                        Container(
                          child: Text(
                            'Total meal calories: ${calories().toString()} cal ',
                            style: FintnessAppTheme.title,
                          ),
                          alignment: Alignment.bottomRight,
                        ),
                        SizedBox(
                          height: 10,
                        ),
                        Container(
                            alignment: Alignment.center,
                            child: Text(
                              'This is your estimated blood glucose after eating this meal: ',
                              style: FintnessAppTheme.title,
                              textAlign: TextAlign.center,
                            )),
                        Text(
                          '${compute()} mg/dL',
                          style: TextStyle(
                            fontFamily: FintnessAppTheme.fontName,
                            fontWeight: FontWeight.w600,
                            fontSize: 28,
                            color: FintnessAppTheme.nearlyDarkBlue,
                          ),
                        ),
                        SizedBox(
                          height: 40,
                        ),
                        Row(
                          mainAxisAlignment: MainAxisAlignment.spaceAround,
                          children: <Widget>[
                            RaisedButton(
                              onPressed: () {
                                Navigator.pushReplacement(
                                    context,
                                    MaterialPageRoute(
                                        builder: (context) =>
                                            FoodManualInput()));
                              },
                              child: Text('Search Again'),
                            ),
                            RaisedButton(
                              onPressed: () {},
                              color: Colors.green,
                              child: Text('Add this food'),
                            ),
                          ],
                        )
                      ],
                    ),
                  )
          ],
        ),
      ),
    );
  }

Вот функции, которые я создал для вычислений:

 void doAction() {
    if (_manualInputKey.currentState.validate()) {
      _manualInputKey.currentState.save();
    }
  }

  double compute() {
    //convert all captures user input to double to be able to compute

    // carbs in nutrient table
    double carbs = double.parse(_carbServSz);
    print('$carbs, ${carbs.runtimeType}');

    // fat in nutrient table
    double fat = double.parse(_fatServSz);
    print('$fat, ${fat.runtimeType}');

    //protein in nutrient table
    double protein = double.parse(_proteinServSz);
    print('$protein, ${protein.runtimeType}');

    // sugar in nutrient table
    double sugar = double.parse(_sugarServSz);
    print('$sugar, ${sugar.runtimeType}');

    // serving size stated in nutrient table
    double servSz = double.parse(_servSize);
    print('$servSz, ${servSz.runtimeType}');

    // estimated servings eaten by user
    double userAte = double.parse(_estServing);
    print('$userAte, ${userAte.runtimeType}');

    double divisor = double.parse(_noOfFood);

    //real computation
    double estimatedBg = 0.0;
    double bloodGlucoseIntercept = 215.3370423;
    double totalCarbs = ((userAte / servSz) * carbs) / divisor;
    print('this is totalCarbs : $totalCarbs');
    estimatedBg =
        (estimatedBg + bloodGlucoseIntercept) + (0.286275132 * totalCarbs);

    showComputation = true;
    return estimatedBg;
  }

  double calories() {

    double carbs = double.parse(_carbServSz);
    print('$carbs, ${carbs.runtimeType}');

    // fat in nutrient table
    double fat = double.parse(_fatServSz);
    print('$fat, ${fat.runtimeType}');

    //protein in nutrient table
    double protein = double.parse(_proteinServSz);
    print('$protein, ${protein.runtimeType}');

    // sugar in nutrient table
    double sugar = double.parse(_sugarServSz);
    print('$sugar, ${sugar.runtimeType}');

    // serving size stated in nutrient table
    double servSz = double.parse(_servSize);
    print('$servSz, ${servSz.runtimeType}');

    // estimated servings eaten by user
    double userAte = double.parse(_estServing);
    print('$userAte, ${userAte.runtimeType}');

    double divisor = double.parse(_noOfFood);

    var totalCalories = ((_estServing / _servSize) * _caloriesSize) / divisor;
    print('this is totalCalories : $totalCalories');

    return totalCalories;
  }

Вот как выглядит страница:

enter image description here

(showComputationVal = false - это логический флаг, показывающий, будет ли страница отображать вычисление или только размерный блок, если для него установлено значение true, он должен отображать вычисления, однако я просто поместил его в текстовый виджет, чтобы узнать, работает ли это условие в моем пользовательском интерфейсе правильно.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...