颤抖:过往未来< int>作为图表的整数 [英] Flutter: passing future<int> as int to Charts
问题描述
我正在使用Flutter开发一种情绪检查器应用程序,其中用户选择了5种表情符号之一来表达自己的情绪。
我想显示一个带有数据表情符号与已选择天数的PieChart。
问题是我必须从sqflite数据库中获取数据才能获得numOfDays,因此选择了特定的表情符号,其类型为Future,但图表无法使用Futures,我尝试使用async-await,但似乎没有
I am making a mood checker application using flutter where user chose one of 5 emojis to tell their mood. I want to display a PieChart with data emoji vs num of Days it has been chosen. Problem is that I have to fetch data from sqflite Database to get numOfDays a particular emoji is chosen which will be of type Future but charts can't take Futures, I tried to use async-await but it didn't seem to work.
错误
E/flutter (27721): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: type 'Future<dynamic>' is not a subtype of type 'int'
E/flutter (27721): #0 _MoodChartState.initData (package:pro_app/journal/view/mood_chart.dart:36:24)
E/flutter (27721): #1 _AsyncAwaitCompleter.start (dart:async/runtime/libasync_patch.dart:49:6)
E/flutter (27721): #2 _MoodChartState.initData (package:pro_app/journal/view/mood_chart.dart:31:16)
E/flutter (27721): #3 _MoodChartState.initState (package:pro_app/journal/view/mood_chart.dart:58:5)
E/flutter (27721): #4 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:3846:58)
E/flutter (27721): #5 ComponentElement.mount (package:flutter/src/widgets/framework.dart:3711:5)
E/flutter (27721): #6 Element.inflateWidget (package:flutter/src/widgets/framework.dart:2956:14)
E/flutter (27721): #7 Element.updateChild (package:flutter/src/widgets/framework.dart:2759:12)
E/flutter (27721): #8 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3747:16)
E/flutter (27721): #9 Element.rebuild (package:flutter/src/widgets/framework.dart:3559:5)
E/flutter (27721): #10 StatelessElement.update (package:flutter/src/widgets/framework.dart:3796:5)
E/flutter (27721): #11 Element.updateChild (package:flutter/src/widgets/framework.dart:2748:15)
E/flutter (27721): #12 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3747:16)
E/flutter (27721): #13 Element.rebuild (package:flutter/src/widgets/framework.dart:3559:5)
E/flutter (27721): #14 ProxyElement.update (package:flutter/src/widgets/framework.dart:4006:5)
E/flutter (27721): #15 Element.updateChild (package:flutter/src/widgets/framework.dart:2748:15)
E/flutter (27721): #16 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3747:16)
E/flutter (27721): #17 Element.rebuild (package:flutter/src/widgets/framework.dart:3559:5)
E/flutter (27721): #18 ProxyElement.update (package:flutter/src/widgets/framework.dart:4006:5)
E/flutter (27721): #19 Element.updateChild (package:flutter/src/widgets/framework.dart:2748:15)
E/flutter (27721): #20 RenderObjectElement.updateChildren (package:flutter/src/widgets/framework.dart:4601:32)
E/flutter (27721): #21 MultiChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4992:17)
E/flutter (27721): #22 Element.updateChild (package:flutter/src/widgets/framework.dart:2748:15)
E/flutter (27721): #23 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3747:16)
E/flutter (27721): #24 Element.rebuild (package:flutter/src/widgets/framework.dart:3559:5)
E/flutter (27721): #25 StatefulElement.update (package:flutter/src/widgets/framework.dart:3894:5)
E/flutter (27721): #26 Element.updateChild (package:flutter/src/widgets/framework.dart:2748:15)
E/flutter (27721): #27 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3747:16)
E/flutter (27721): #28 Element.rebuild (package:flutter/src/widgets/framework.dart:3559:5)
E/flutter (27721): #29 ProxyElement.update (package:flutter/src/widgets/framework.dart:4006:5)
E/flutter (27721): #30 Element.updateChild (package:flutter/src/widgets/framework.dart:2748:15)
E/flutter (27721): #31 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3747:16)
E/flutter (27721): #32 Element.rebuild (package:flutter/src/widgets/framework.dart:3559:5)
E/flutter (27721): #33 StatefulElement.update (package:flutter/src/widgets/framework.dart:3894:5)
E/flutter (27721): #34 Element.updateChild (package:flutter/src/widgets/framework.dart:2748:15)
E/flutter (27721): #35 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4883:14)
E/flutter (27721): #36 Element.updateChild (package:flutter/src/widgets/framework.dart:2748:15)
E/flutter (27721): #37 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3747:16)
E/flutter (27721): #38 Element.rebuild (package:flutter/src/widgets/framework.dart:3559:5)
E/flutter (27721): #39 StatelessElement.update (package:flutter/src/widgets/framework.dart:3796:5)
E/flutter (27721): #40 Element.updateChild (package:flutter/src/widgets/framework.dart:2748:15)
E/flutter (27721): #41 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4883:14)
E/flutter (27721): #42 Element.updateChild (package:flutter/src/widgets/framework.dart:2748:15)
E/flutter (27721): #43 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3747:16)
E/flutter (27721): #44 Element.rebuild (package:flutter/src/widgets/framework.dart:3559:5)
E/flutter (27721): #45 StatefulElement.update (package:flutter/src/widgets/framework.dart:3894:5)
E/flutter (27721): #46 Element.updateChild (package:flutter/src/wid
情绪模型文件
import'package:flutter / material.dart';
import 'package:flutter/material.dart';
class Mood {
int _moodID;
int _emojiID;
int _actID;
int _moodDay;
int _moodMonth;
int _moodYear;
Mood(this._emojiID, this._moodDay, this._moodMonth, this._moodYear,
this._actID);
Mood.withId(this._moodID, this._emojiID, this._moodDay, this._moodMonth,
this._moodYear, this._actID);
int get moodID => _moodID;
int get emojiID => _emojiID;
int get actID => _actID;
int get moodDay => _moodDay;
int get moodMonth => _moodMonth;
int get moodYear => _moodYear;
// can define setters as well
Map<String, int> toMap() {
var map = Map<String, int>();
if (_moodID != null) {
map['moodId'] = _moodID;
}
map['emojiId'] = _emojiID;
map['actId'] = _actID;
map['moodDay'] = _moodDay;
map['moodMonth'] = _moodMonth;
map['moodYear'] = _moodYear;
return map;
}
Mood.fromMap(Map<String, int> map) {
this._moodID = map['moodId'];
this._emojiID = map['emojiId'];
this._actID = map['actId'];
this._moodDay = map['moodMap'];
this._moodMonth = map['moodMonth'];
this._moodYear = map['moodYear'];
}
}
*数据库文件
import 'package:path/path.dart';
import 'dart:async';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
import 'dart:io';
import '../models/mood_model.dart';
class DatabaseHelper {
static final DatabaseHelper _instance = new DatabaseHelper.internal();
factory DatabaseHelper() => _instance;
final String tableName = "moodTable";
final String colMoodId = "moodId";
final String colEmojiId = "emojiId";
final String colActId = "actId";
final String colMoodDay = "moodDay";
final String colMoodMonth = "moodMonth";
final String colMoodYear = "moodYear";
static Database _db;
Future<Database> get db async {
if (_db == null) {
return initDb();
}
return _db;
}
DatabaseHelper.internal();
Future<Database> initDb() async {
Directory documentDirectory = await getApplicationDocumentsDirectory();
String path = join(documentDirectory.path, "mood.db");
var ourDb = await openDatabase(path, version: 1, onCreate: _onCreate);
return ourDb;
}
void _onCreate(Database db, int version) async {
await db.execute(
"CREATE TABLE moodTable (moodId INTEGER PRIMARY KEY, emojiId INTEGER, actId INTEGER, moodDay INTEGER, moodMonth INTEGER, moodYear INTEGER)");
print("Table Created");
}
// insert
Future<int> saveMood(Mood mood) async {
var dbClient = await this.db;
int result = await dbClient.insert("$tableName", mood.toMap());
print('Saved');
return result;
}
// to get number of mood days
Future<List<Map<String, dynamic>>> listOfMoods() async {
Database db = await this.db;
var result = await db.query(tableName, orderBy: '$colMoodId ASC');
return result;
}
Future<int> numOfMoodDays(int emojiID) async {
Database db = await this.db;
var result = await db.query(tableName,
orderBy: '$colMoodId ASC',
where: '$colEmojiId = ?',
whereArgs: [emojiID]);
return result.length;
}
// close db
Future close() async {
var dbClient = await db;
return dbClient.close();
}
}
Mood_Chart文件摘要
import 'package:flutter/material.dart';
import 'dart:math';
import 'package:charts_flutter/flutter.dart' as charts;
import '../view/mood.dart';
import '../models/mood_db.dart';
import 'dart:async';
class Mood {
String _emoji;
int _numOfDays; // this has to int bcz charts can't take future<int>
charts.Color _color;
Mood(this._emoji, this._numOfDays, this._color);
}
class MoodChart extends StatefulWidget {
@override
_MoodChartState createState() => _MoodChartState();
}
class _MoodChartState extends State<MoodChart> {
DatabaseHelper _databaseHelper = DatabaseHelper();
List<Mood> _data;
List<charts.Series<Mood, String>> _chartData;
// Here I used async-await but this function still return Future<int>
numOfDaysFn(int id) async {
int numOfDays =await _databaseHelper.numOfMoodDays(id);
return numOfDays;
}
void initData() async {
_chartData = List<charts.Series<Mood, String>>();
_data = <Mood>[
Mood(
allMoods[0], numOfDaysFn(1), charts.MaterialPalette.red.shadeDefault),
Mood(allMoods[1], numOfDaysFn(2),
charts.MaterialPalette.blue.shadeDefault),
Mood(allMoods[2], numOfDaysFn(3),
charts.MaterialPalette.gray.shadeDefault),
Mood(allMoods[3], numOfDaysFn(4),
charts.MaterialPalette.indigo.shadeDefault),
Mood(allMoods[4], numOfDaysFn(5),
charts.MaterialPalette.green.shadeDefault),
];
_chartData.add(charts.Series(
id: 'Mood',
data: _data,
colorFn: (Mood mood, _) => mood._color,
domainFn: (Mood mood, _) => mood._emoji,
measureFn: (Mood mood, _) => **mood._numOfDays**, //this can't take futures
));
}
@override
void initState() {
super.initState();
initData();
}
@override
Widget build(BuildContext context) {
return Container(
child: charts.PieChart(
_chartData,
animate: true,
),
);
}
}
List allMoods = ['Disgusting', 'Bad', 'Ok', 'Good', 'Amazing'];
推荐答案
我不知道这段代码是否运行,因为您的示例代码不完整。
您有点需要学习飞镖期货的工作原理。当您调用它时,结果将像Javascript Promise一样稍后返回
I do not know if this code runs because your sample code is not complete. You kinda need to learn how dart futures work. When you call it, the result will return later like Javascript promises
import 'package:flutter/material.dart';
import 'dart:math';
import 'package:charts_flutter/flutter.dart' as charts;
import '../view/mood.dart';
import '../models/mood_db.dart';
import 'dart:async';
class Mood {
String _emoji;
int _numOfDays; // this has to int bcz charts can't take future<int>
charts.Color _color;
Mood(this._emoji, this._numOfDays, this._color);
}
class MoodChart extends StatefulWidget {
@override
_MoodChartState createState() => _MoodChartState();
}
class _MoodChartState extends State<MoodChart> {
DatabaseHelper _databaseHelper = DatabaseHelper();
List<Mood> _data;
List<charts.Series<Mood, String>> _chartData = null;
// Here I used async-await but this function still return Future<int>
Future<List<int>> numOfDaysFn(List<int> days) async {
return Future.wait(days.map((d) => _databaseHelper.numOfMoodDays(d)));
}
void initData( List<int> idx, List<int> days) {
setState(() {
_chartData = List<charts.Series<Mood, String>>();
_data = <Mood>[
Mood(
allMoods[idx[0]-1], days[0], charts.MaterialPalette.red.shadeDefault),
Mood(allMoods[idx[1]-1], days[1],
charts.MaterialPalette.blue.shadeDefault),
Mood(allMoods[idx[2]-1], days[2],
charts.MaterialPalette.gray.shadeDefault),
Mood(allMoods[idx[3]-1], days[3],
charts.MaterialPalette.indigo.shadeDefault),
Mood(allMoods[idx[4]-1], days[4],
charts.MaterialPalette.green.shadeDefault),
];
_chartData.add(charts.Series(
id: 'Mood',
data: _data,
colorFn: (Mood mood, _) => mood._color,
domainFn: (Mood mood, _) => mood._emoji,
measureFn: (Mood mood, _) => mood._numOfDays, //this can't take futures
));
});
}
@override
void initState() {
super.initState();
var months = [1,2,3,4,5];
numOfDaysFn(months).then((days) {
initData(months, days);
});
}
@override
Widget build(BuildContext context) {
if(_chartData != null ){
return Container(
child: charts.PieChart(
_chartData,
animate: true,
),
);
} else {
return CircularProgressIndicator();
}
}
}
修订版1
import 'package:flutter/material.dart';
import 'dart:math';
import 'package:charts_flutter/flutter.dart' as charts;
import '../view/mood.dart';
import '../models/mood_db.dart';
import 'dart:async';
class Mood {
String _emoji;
int _numOfDays; // this has to int bcz charts can't take future<int>
charts.Color _color;
Mood(this._emoji, this._numOfDays, this._color);
}
class MoodChart extends StatefulWidget {
@override
_MoodChartState createState() => _MoodChartState();
}
class _MoodChartState extends State<MoodChart> {
DatabaseHelper _databaseHelper = DatabaseHelper();
List<Mood> _data;
List<charts.Series<Mood, String>> _chartData = null;
static List<charts.Color> DEFAULT_SHADE = [
null,
charts.MaterialPalette.red.shadeDefault,
charts.MaterialPalette.blue.shadeDefault,
charts.MaterialPalette.gray.shadeDefault,
charts.MaterialPalette.indigo.shadeDefault,
charts.MaterialPalette.green.shadeDefault];
Future<Mood> numOfDaysFn(int day) async {
return Mood( allMood[day-1] , _databaseHelper.numOfMoodDays(day), DEFAULT_SHADE[day] );
}
Future<List<Mood>> returnAllNumOfDaysFn( List<int> days) async {
return Future.wait(days.map((d) => numOfDaysFn(d)));
}
@override
void initState() {
super.initState();
var months = [1,2,3,4,5];
returnAllNumOfDaysFn(months).then((moods) {
var temp = charts.Series(
id: 'Mood',
data: _data,
colorFn: (Mood mood, _) => mood._color,
domainFn: (Mood mood, _) => mood._emoji,
measureFn: (Mood mood, _) => mood._numOfDays, //this can't take futures
);
setState(() {
_data = moods;
_chartData = temp;
});
});
}
@override
Widget build(BuildContext context) {
if(_chartData != null ){
return Container(
child: charts.PieChart(
_chartData,
animate: true,
),
);
} else {
return CircularProgressIndicator();
}
}
}
https://www.dartlang.org/guides/libraries/futures-error-handling
https:// docs.flutter.io/flutter/widgets/State/initState.html
https://www.dartlang.org/tutorials/language/futures#calling-multiple-funcs
编辑:您也需要了解setState
you need to understand setState too
https://docs.flutter.io/flutter/widgets/State/setState.html
扑动图为样本提供静态数据。但是,您正在动态获取数据,因此需要调用设置状态。
Flutter charts provide sample with static data. However, you are fetching data dynamically so you need to call set state.
这篇关于颤抖:过往未来< int>作为图表的整数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!