我正在使用颤动做一个情绪检查应用程序,用户选择5个表情符号中的一个来表达他们的心情。我想显示一个带有数据表情符号的PieChart与已选择的天数。问题是我必须从sqflite数据库中获取数据以获取numOfDays选择一个特定的表情符号,它将是Future类型,但图表不能采用Futures,我试图使用async-await但它似乎不起作用。
错误
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';
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 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
https://docs.flutter.io/flutter/widgets/State/setState.html
Flutter图表提供静态数据样本。但是,您正在动态获取数据,因此您需要调用set state。