«Вызов метода» был вызван с нулевым значением ». в Flutter - PullRequest
0 голосов
/ 03 августа 2020

Я пытаюсь извлечь значение touchedIndex из дочернего виджета PieChartWidget, которое мне нужно сделать диаграмму ap ie с отверстием посередине с помощью fl_chart, в его родительский виджет Co2Tracker, чтобы разрешить me, чтобы создать текст в середине диаграммы p ie, который изменяется при нажатии сегмента диаграммы p ie. Это возвращает ошибку, но все работает визуально, кроме сегментов диаграммы p ie, больше не расширяются. Чтобы упростить отладку, я заменил setState(){isTouched = isTouchedNew} на print(isTouchedNew), но это все равно возвращает ошибку ниже, однако p ie диаграмма теперь расширяется.

Пример PieChart

При использовании функции обратного вызова

int isTouched = -1;
setIsTouched(int isTouchedNew) {
  print(isTouchedNew);
}

, интегрированной в виджет с отслеживанием состояния, я получаю результат

════════ Exception caught by gesture ═══════════════════════════════════════════════════════════════
The method 'call' was called on null.
Receiver: null
Tried calling: call(-1)

родительская главная страница

class Co2Tracker extends StatefulWidget {
  @override
  _Co2TrackerState createState() => _Co2TrackerState();
}

class _Co2TrackerState extends State<Co2Tracker> {

  List<String> pieNames = ['Travel', 'Gas', 'Electricity', 'Food shop', 'Water',];

  int isTouched = -1;
  double radiusNormal = 60;
  double centerRadius = 50;
  double radiusExpansion = 1.2;

  setIsTouched(int isTouchedNew) {
    print(isTouchedNew);
  }

  @override
  Widget build(BuildContext context) {

    //double co2 = ModalRoute.of(context).settings.arguments;

    return Scaffold(
      appBar: appBarTemplate('CO\u2082 Tracker'),
      body: Column(
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.symmetric(vertical: 15),
            child: textStyleTemplateLarge(text: 'Your CO\u2082 emissions today', textColor: Colors.green[400]),
          ),
          AspectRatio(
            aspectRatio: 200/((radiusExpansion*radiusNormal) + centerRadius),
            child: Row(
              children: <Widget>[
                Expanded(
                  child: Stack(
                    children: <Widget>[
                      Center(
                        child: FlatButton(child: textStyleTemplateLarge(text: '70kg', textColor: Colors.black),),
                      ),
                      Center(
                          child: PieChartWidget(radiusNormal: radiusNormal, centerRadius: centerRadius, radiusExpanded: (radiusExpansion*radiusNormal), pieNames: pieNames,),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

дочерний p ie виджет диаграммы

import 'package:flutter/material.dart';
import 'package:fl_chart/fl_chart.dart';

class PieChartWidget extends StatefulWidget {
  final double radiusNormal;
  final double radiusExpanded;
  final double centerRadius;
  final double fontSizeNormal;
  final double fontSizeExpanded;
  final List<String> pieNames;
  final Function(int) setIsTouched;

  PieChartWidget({this.radiusNormal, this.radiusExpanded, this.centerRadius, this.fontSizeNormal, this.fontSizeExpanded, this.pieNames, this.setIsTouched});



  @override
  _PieChartWidgetState createState() => _PieChartWidgetState(radiusNormal: radiusNormal, radiusExpanded: radiusExpanded, centerRadius: centerRadius,
    fontSizeNormal: fontSizeNormal, fontSizeExpanded: fontSizeExpanded, pieNames: pieNames, setIsTouched: setIsTouched,);
}

class _PieChartWidgetState extends State<PieChartWidget> {
  int touchedIndex = -1;
  double radiusNormal;
  double radiusExpanded;
  double centerRadius;
  double fontSizeNormal;
  double fontSizeExpanded;
  List<String> pieNames;
  Function(int) setIsTouched;

  _PieChartWidgetState({this.radiusNormal = 50, this.radiusExpanded = 60, this.centerRadius = 40, this.fontSizeNormal = 16, this.fontSizeExpanded = 25,
    this.pieNames, this.setIsTouched,});

  @override
  Widget build(BuildContext context) {
    return PieChart(
      PieChartData(
        sections: pieSections(pieNames),
        borderData: FlBorderData(show: false),
        sectionsSpace: 0,
        centerSpaceRadius: centerRadius,
        pieTouchData: PieTouchData(touchCallback: (pieTouchResponse) {
          setState(() {
            if (pieTouchResponse.touchInput is FlLongPressEnd ||
                pieTouchResponse.touchInput is FlPanEnd) {
              touchedIndex = -1;
            } else {
              touchedIndex = pieTouchResponse.touchedSectionIndex;
            }
          });
          widget.setIsTouched(touchedIndex);
        }),
      ),
    );
  }

-----------------I-think-everything-below-this-is-irrelevant-but-I-could-be-wrong-------------------------------------------

  List<PieChartSectionData> pieSections(List<String> pieNames,) {
    return List.generate(5, (i) {
      final isTouched = i == touchedIndex;
      final double fontSize = isTouched ? 25 : 16;
      final double radius = isTouched ? radiusExpanded : radiusNormal;
      final int colorNumber = (1+i) * 100;
      final List<double> valueList = [20, 10, 10, 20, 30];
      final double total = valueList.fold(0, (a, b) => a+b);
      switch (i) {
        case 0:
          return sectionData(valueList[i], Colors.pink[300], title(isTouched, valueList[i], total, pieNames[i]), radius, fontSize);
        case 1:
          return sectionData(valueList[i], Colors.blue[600], title(isTouched, valueList[i], total, pieNames[i]), radius, fontSize);
        case 2:
          return sectionData(valueList[i], Colors.amber[300], title(isTouched, valueList[i], total, pieNames[i]), radius, fontSize);
        case 3:
          return sectionData(valueList[i], Colors.purple[300], title(isTouched, valueList[i], total, pieNames[i]), radius, fontSize);
        case 4:
          return sectionData(valueList[i], Colors.blue[300], title(isTouched, valueList[i], total, pieNames[i]), radius, fontSize);
        default:
          return null;
      }
    });
  }
  PieChartSectionData sectionData(double value, Color color, String title, double radius, double fontSize,){
    return PieChartSectionData(
      value: value, color: color, title: title, radius: radius,
      titleStyle: TextStyle(color: Colors.black, fontSize: fontSize, fontWeight: FontWeight.bold),
    );
  }
  String title(bool isTouched, double value, double total, String title,) {
    return isTouched ? '${double.parse((value/total*100).toStringAsFixed(2))}%' : '$title';
  }
}

До сих пор я думал, что, возможно, это связано с инициализацией переменные или, может быть, эту touchCallback функцию из строки 43 дочерней страницы, но пока безуспешно. Заранее благодарим за уделенное время.

Ответы [ 2 ]

0 голосов
/ 03 августа 2020

Ммм .. не уверен, пробовали ли вы это,

int isTouched = -1;


setIsTouched(int isTouchedNew) {
setState(() {

isTouched=isTouchedNew;
  print(isTouchedNew);
}
}
0 голосов
/ 03 августа 2020

Проблема в том, что когда вы печатаете целое число.

setIsTouched(int isTouchedNew) { print(isTouchedNew); }

Вы должны печатать это так

print("${isTouchedNew}")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...