Flutter编译代码后如何设置状态
How to setState after code has been compiled Flutter
我正在尝试构建一个使用 SQFLite 存储数据的聊天应用程序。只有一个错误我可以找到答案。错误是 setState 首先被调用,然后它会编译其余的代码。这是我的做法,你能帮帮我吗?
main.dart
class _ChatState extends State<Chat> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Text'),
),
body: Container(
child: Column(
children: [
Expanded(
flex: 20,
child: SizedBox(
height: MediaQuery.of(context).size.height * .8,
child: Container(
child: FutureBuilder(
// This is where the messages are being loaded and displayed
future: messages(dbName),
builder: (BuildContext context, snapshot) {
if (snapshot.hasData) {
return snapshot.data;
} else {
return Container();
}
},
),
),
),
),
Expanded(
flex: 3,
child: Container(
child: Row(
children: [
Expanded(
flex: 12,
child: TextField(
onChanged: (text) async {
print(text);
message = text;
},
),
),
Expanded(
flex: 2,
child: MaterialButton(
child: Text(''),
onPressed: () {
setState(() {
// This is where the problem has to be fixed.
var typing;
connectToServer(typing, message);
// Trying to call setState once again but it doesn't fix the issue
setState(
() {},
);
})
},
),
),
],
),
),
),
],
),
),
);
}
}
server.dart
void connectToServer(typing, message) async {
// Store message to SQFlite.
if (message != null) {
sendMessage() async {
// Store message in SQFlite
var locDb = await openDatabase('chats.db');
String dbName = emailUser + friendName;
//await locDb.execute('DROP TABLE $dbName');
await locDb.execute(
'CREATE TABLE IF NOT EXISTS $dbName (_id INTEGER, sender TEXT, reciever TEXT, message TEXT, timestamp TEXT, recieved TEXT)',
);
await locDb.rawInsert(
'INSERT INTO $dbName(_id, sender, reciever, message, timestamp, recieved) VALUES("$_id", "$emailUser", "$friendName", "$message", "$timeStamp", "FALSE")',
);
messages(dbName);
await locDb.close();
}
return sendMessage();
}
}
getMessages.dart
class MessageClass {
final String id;
final String emailUser;
final String friendName;
final String message;
final String timeStamp;
final String recieved;
MessageClass({
this.id,
this.emailUser,
this.friendName,
this.message,
this.timeStamp,
this.recieved,
});
}
Future<void> messages(dbName) async {
var locDb = await openDatabase('chats.db');
List<Map> messages = await locDb.rawQuery('SELECT * FROM $dbName');
return Container(
height: 200,
child: ListView(
controller: _scrollController,
scrollDirection: Axis.vertical,
children: List.generate(
messages.length,
(i) {
var _message = MessageClass(
id: messages[i]['id'],
emailUser: messages[i]['emailUser'],
friendName: messages[i]['friendName'],
message: messages[i]['message'],
timeStamp: messages[i]['timeStamp'],
recieved: messages[i]['recieved'],
);
return GridTile(
child: Row(
children: [
_message.recieved.toString() == 'FALSE'
? Spacer()
: Container(),
Text(
_message.message.toString(),
),
],
),
);
},
),
),
);
}
我知道代码很长,但也许你已经找到了除 setState 之外的其他方法。提前致谢!
onPressed: () async {
//setState(() {});
var typing;
await connectToServer(typing, message);
setState(() {});
},
不要忘记异步等待。并使用一个 setState.
我正在尝试构建一个使用 SQFLite 存储数据的聊天应用程序。只有一个错误我可以找到答案。错误是 setState 首先被调用,然后它会编译其余的代码。这是我的做法,你能帮帮我吗?
main.dart
class _ChatState extends State<Chat> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Text'),
),
body: Container(
child: Column(
children: [
Expanded(
flex: 20,
child: SizedBox(
height: MediaQuery.of(context).size.height * .8,
child: Container(
child: FutureBuilder(
// This is where the messages are being loaded and displayed
future: messages(dbName),
builder: (BuildContext context, snapshot) {
if (snapshot.hasData) {
return snapshot.data;
} else {
return Container();
}
},
),
),
),
),
Expanded(
flex: 3,
child: Container(
child: Row(
children: [
Expanded(
flex: 12,
child: TextField(
onChanged: (text) async {
print(text);
message = text;
},
),
),
Expanded(
flex: 2,
child: MaterialButton(
child: Text(''),
onPressed: () {
setState(() {
// This is where the problem has to be fixed.
var typing;
connectToServer(typing, message);
// Trying to call setState once again but it doesn't fix the issue
setState(
() {},
);
})
},
),
),
],
),
),
),
],
),
),
);
}
}
server.dart
void connectToServer(typing, message) async {
// Store message to SQFlite.
if (message != null) {
sendMessage() async {
// Store message in SQFlite
var locDb = await openDatabase('chats.db');
String dbName = emailUser + friendName;
//await locDb.execute('DROP TABLE $dbName');
await locDb.execute(
'CREATE TABLE IF NOT EXISTS $dbName (_id INTEGER, sender TEXT, reciever TEXT, message TEXT, timestamp TEXT, recieved TEXT)',
);
await locDb.rawInsert(
'INSERT INTO $dbName(_id, sender, reciever, message, timestamp, recieved) VALUES("$_id", "$emailUser", "$friendName", "$message", "$timeStamp", "FALSE")',
);
messages(dbName);
await locDb.close();
}
return sendMessage();
}
}
getMessages.dart
class MessageClass {
final String id;
final String emailUser;
final String friendName;
final String message;
final String timeStamp;
final String recieved;
MessageClass({
this.id,
this.emailUser,
this.friendName,
this.message,
this.timeStamp,
this.recieved,
});
}
Future<void> messages(dbName) async {
var locDb = await openDatabase('chats.db');
List<Map> messages = await locDb.rawQuery('SELECT * FROM $dbName');
return Container(
height: 200,
child: ListView(
controller: _scrollController,
scrollDirection: Axis.vertical,
children: List.generate(
messages.length,
(i) {
var _message = MessageClass(
id: messages[i]['id'],
emailUser: messages[i]['emailUser'],
friendName: messages[i]['friendName'],
message: messages[i]['message'],
timeStamp: messages[i]['timeStamp'],
recieved: messages[i]['recieved'],
);
return GridTile(
child: Row(
children: [
_message.recieved.toString() == 'FALSE'
? Spacer()
: Container(),
Text(
_message.message.toString(),
),
],
),
);
},
),
),
);
}
我知道代码很长,但也许你已经找到了除 setState 之外的其他方法。提前致谢!
onPressed: () async {
//setState(() {});
var typing;
await connectToServer(typing, message);
setState(() {});
},
不要忘记异步等待。并使用一个 setState.