我有一个StatefulWidget,它应该根据条件从MySQL数据库中检索数据,并将检索到的值添加到数组中,这样我就可以使用数组值在ListView上显示。我的问题是,有时当数组(_fileValues
)和_custUsername
变量为空或未更新时,不会抛出异常。
这是我的statefulwidget(main.dart
)
String? _custUsername;
List<String> _fileValues = <String>[];
class cakeLogin extends StatefulWidget {
@override
cakeLoginPageMain createState() => cakeLoginPageMain();
}
class cakeLoginPageMain extends State<cakeLogin> {
String? _CustEmailInit;
BuildContext? loginContext;
List<String> _fileNameStores = <String>[];
void callData() {
// @ Get username based on user email and assign it to _custUsername variable
UsernameGetter().Connection(_CustEmailInit!).then((UsernameValue) {
_custUsername = UsernameValue!;
});
// @ Get item names based on the user username (_custUsername) and add them into
// _fileNameStores
NameGetter().Connection(_custUsername).then((NamesValues) {
for(var _nameItems in NamesValues) {
setState(() {
_fileNameStores.add(_nameItems);
});
}
});
// @ Remove duplicates value and add them into main list (_fileValues)
var _removeDuplicates = _fileNameStores.toSet().toList();
for(var item in _removeNamesDupes) {
setState(() {
_fileValues.add(item);
});
}
}
@override
Widget build(BuildContext context) {
final _emailController = TextEditingController();
return Scaffold(
appBar: AppBar(
title: Text("Login to App",
style: TextStyle(
fontSize: 18,
color: setupFontCol,
fontWeight: FontWeight.bold
)),
backgroundColor: setupThemeBar,
centerTitle: true,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
)
),
backgroundColor: setupMainTheme,
body: Padding(
padding: EdgeInsets.all(20),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextFormField(
controller: _emailController,
style: TextStyle(color: Color.fromARGB(255, 214, 213, 213)),
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
filled: true,
hintStyle: TextStyle(color: Color.fromARGB(255, 197, 197, 197)),
hintText: "Enter your email",
fillColor: setupThemeBar
),
),
SizedBox(height: 18),
SizedBox(height: 25),
SizedBox(
height: 45,
width: 500,
child: ElevatedButton(
style:
ElevatedButton.styleFrom(
primary: setupFontCol,
onPrimary: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
)
),
onPressed: () {
var _CustEmail = _emailController.text;
if(_CustEmail.contains("@gmail.com") || _CustEmail.contains("@email.com")) {
if(_CustEmail != "") {
_CustEmailInit = _CustEmail;
loginContext = context;
_isFromLogin = true;
_fileValues.clear();
callData();
} else {
alertDialog("Please enter your email address",context);
}
} else {
alertDialog("Email address is not valid",context);
}
},
//color: setupFontCol,
child: Text("Login",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.normal,
fontSize: 14,
))
),
),
],
),
),
);
}
}
UsernameGetter
类(此类将根据文本字段输入的电子邮件从数据库表中检索用户用户名)
当我从UsernameGetter
类打印_usernameDetected
时,它返回返回字符串的更新版本,但当我从main.dart
将_custUsername
赋值给UsernameValue
时,它不更新,有时返回空值。
import 'package:mysql_client/mysql_client.dart';
import 'dart:convert';
import 'dart:ffi';
import 'dart:typed_data';
import 'package:signuppage/main.dart' as main;
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
class UsernameGetter {
Future<String> Connection(String _custEmail) async {
final conn = await MySQLConnection.createConnection(
host: "",
port: ,
userName: "",
password: "",
databaseName: "",
);
await conn.connect();
var _getUsernameQue = await conn.execute("SELECT CUST_USERNAME FROM information WHERE CUST_EMAIL = :email",
{
"email": _custEmail
});
String? _usernameDetected;
for(final _rowsOfEmail in _getUsernameQue.rows) {
_usernameDetected = _rowsOfEmail.assoc()['CUST_USERNAME']!;
}
return await _usernameDetected!;
}
}
NameGetter
类(检索存储在文本列中的用户项名称)
对于NameGetter
类,发生与UsernameGetter
相同的情况。当我从main.dart
中检索值并将值添加到_fileValues
列表中时,有时值为空,有时值未更新。
import 'package:mysql_client/mysql_client.dart';
import 'dart:convert';
import 'dart:ffi';
import 'dart:typed_data';
import 'package:signuppage/main.dart' as main;
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
class NameGetter {
Future<List<String>> Connection(String _custUsername) async {
final conn = await MySQLConnection.createConnection(
host: "",
port: ,
userName: "",
password: "",
databaseName: "",
);
await conn.connect();
var _getItemNames= await conn.execute("SELECT ITEM_NAMES FROM item_details WHERE CUST_USERNAME = :username",
{
"username": _custUsername
});
List<String>? _itemNamesValues= <String>[];
for(var _rowsOfItemNames in _getItemNames.rows) {
var _retrieveNames = await _rowsOfItemNames.assoc()['ITEM_NAMES']!;
_itemNamesValues.add(_retrieveNames);
}
return await _itemNamesValues;
}
}
我不确定我的错误在哪里,我很确定我犯了很多错误,我需要有人帮我弄清楚。特别是为什么列表和变量没有更新/有时是空的。
参考链接:
Flutter ListView not updating
my list in flutter is not updating the problem in my code
Why variable value is not refreshing in flutter?
1条答案
按热度按时间fhg3lkii1#
问题
callData()
方法的简化版本如下所示:如前所述,
anotherAsyncFunction(foo)
的调用紧跟在someAsyncFunction()
之后,* 在 *then()
之前,then()
赋值给foo
。您可以通过策略性地插入
print()
语句来观察这种行为。解决方案
本质上,
Future.then()
和async
/await
是一回事,然而,人们通常更容易理解使用async
/await
时异步代码的行为,因为这样读起来就像顺序执行的代码。虽然您可以使用其中的任何一种,但我建议您转到
async
/await
,以使代码在阅读时更容易理解。下面是一个如何重构
callData()
的例子:以这种方式编写,很明显
custUsername
是在调用NameGetter().Connection(custUsername)
之前赋值的。确保通读Asynchronous programming: futures, async, await。