如何在编译Flutter代码后设置State



我正在尝试构建一个使用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。

最新更新