когда я добавляю поздно в " List<charts.Series<Sales,String>> _seriesBarData;"
это показывает мне эту ошибку:
LateInitializationError: поле '_seriesBarData@905436988' не было инициализировано. а затем, когда я удаляю его и добавляю '?'
это показывает мне эту ошибку
Ошибка: тип аргумента «Список<Серия<Продажи, Строка>>?» не может быть присвоен типу параметра «Список<Серия<динамический, Строка>>», поскольку «Список<Серия<Продажи, Строка>>?» допускает значение NULL, а 'List<Series<dynamic, String>>' — нет.
вот мой код
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'Model/sales.dart';
import 'package:charts_flutter/flutter.dart' as charts;
import 'rounded_button.dart';
class ChartScreen extends StatefulWidget {
@override
_ChartScreenState createState() => _ChartScreenState();
}
class _ChartScreenState extends State<ChartScreen> {
late List<charts.Series<Sales,String>> _seriesBarData;
List<Sales>? myData ;
_generateData(myData){
_seriesBarData = <charts.Series<Sales,String>>[];
_seriesBarData?.add(
charts.Series(
domainFn : (Sales sales,_) => sales.saleYear.toString() ,
measureFn : (Sales sales,_) => sales.saleVal,
colorFn : (Sales sales,_) => charts.ColorUtil.fromDartColor(Color(int.parse(sales.colorVal))),
id:"Sales",
data: myData ,
labelAccessorFn: (Sales row,_) => "${row.saleYear}"
)
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: _buildBody(context),
);
}
Widget _buildBody(BuildContext context){
return StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance.collection('sales').snapshots(),
builder: (context,snapshot){
if (!snapshot.hasData){
return LinearProgressIndicator();
}
else{
List<Sales> sales = snapshot.data!.docs
.map((snapshot) => Sales.fromMap(snapshot.data() as Map<String,dynamic>))
.toList();
return _buildChart(context, sales);
}
},
);
}
Widget _buildChart(BuildContext context , List<Sales> saledata){
List<Sales> myData ;
myData = saledata;
_generateData(myData){};
return Padding(
padding: EdgeInsets.all(8.0),
child: Container(
child: Center(
child:Column(
children: <Widget>[
Text ('Sales by Year',
style:TextStyle(fontSize:24.0 , fontWeight: FontWeight.bold),
),
SizedBox(height : 10.0, ),
Expanded(
child: charts.BarChart(_seriesBarData,
/*animate : true,
animationDuration: Duration(seconds:5),*/
behaviors : [
new charts.DatumLegend(
entryTextStyle : charts.TextStyleSpec(color: charts.MaterialPalette.purple.shadeDefault,
fontFamily: 'Google',
fontSize:18),
)
],
),
),
],
),
),
),
);
}
}
Во-первых, так как параметр "myData" обнуляется, то вам нужно написать его так myData!
также удалить слово поздно late List<charts.Series<Sales,String>> _seriesBarData;
также сделать как List<charts.Series<Sales,String>> _seriesBarData = <charts.Series<Sales,String>>[];
так что я думаю, что ваша проблема будет решена.
Это не удастся, если myData
будет null
Возможно, это была ошибка при копировании вашего кода в SO, но, глядя на ваш вызов _generateData
, он кажется неправильным:
_generateData(myData){};
Это должно быть просто
_generateData(myData);
В этом случае имеет смысл получить ошибку, так как далее вы вызываете
charts.BarChart(
_seriesBarData,
...
)
И если BarChart
станет нулевым (ваше начальное значение), ваша программа рухнет.
Я согласен с другим комментатором в том, что вы можете инициализировать свой массив при его объявлении, что гарантирует отсутствие сбоев (хотя, если вы не исправите вызов функции, список останется пустым).
List<charts.Series<Sales, String>> _seriesBarData = [];
Вы добавили
?
в определение списка (late List<charts.Series<Sales,String>> _seriesBarData;
) или при назначении списка (в строке_seriesBarData = <charts.Series<Sales,String>>[];
)? Потому что добавление его в определение списка должно быть в порядке, например:List<charts.Series<Sales,String>>? _seriesBarData;