【发布时间】:2021-11-07 23:13:37
【问题描述】:
我的 Provider 类中有一个方法 login,在 HomeScreen() 的 initState() 方法中调用,在 login function 中我基本上注册/检查用户信息是否存储在服务器中,然后我向服务器发布请求以获取该用户的信息。一切正常但是当我hot restart 或reopens 应用程序时,它会继续加载,因为显然三元运算不满足但如果我在login 函数中打印数据,它确实发生了变化,因此,notifyListeners() 无法正常工作,因此状态没有改变。 (现在我必须hot reloadctrl+s,然后状态发生变化,一切都加载成功)。
主屏幕():
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
List<Course> courses = [];
@override
void initState() {
super.initState();
courses = Course().getAllCourses();
Future.delayed(Duration.zero, () async {
Provider.of<LoginProvider>(context, listen: false).login();
});
}
@override
Widget build(BuildContext context) {
bool isLoading =
Provider.of<LoginProvider>(context, listen: false).isLoading;
User user = Provider.of<LoginProvider>(context, listen: false).user;
print("INITIAL: $isLoading");
print("INITIAL: ${user.data!.categoryList!.length}");
return Scaffold(
backgroundColor: Colors.white,
body: !isLoading && user.data != null
? ListView.separated(
itemCount: courses.length,
separatorBuilder: (context, index) {
return Divider();
},
itemBuilder: (context, index) {
final course = courses[index];
final courseNew = user.data!.categoryList![index];
print("INSIDE: $isLoading");
print("INSIDE: ${user.data!.categoryList!.length}");
if (courses.length == user.data!.categoryList!.length) {
return ... // full custom
}
return Center(
child: Text("No Data recieved from backend"),
);
},
)
: Center(
child: CircularProgressIndicator(
strokeWidth: 4,
)),
);
}
}
(courses 和 user.data.categoryList 的长度相同)
Provider文件中的登录功能:
login() async {
await _checkIsUserLoggedIn();
if (_deviceDetails.deviceID == "") {
print("[INFO] NEW USER DEVICE DETECTED");
print("[INFO] LOGGING IN...");
await _getDeviceDetails();
// fetching platform details, if success, carry-on, else throw error
try {
if (_deviceDetails.deviceID != "") {
// post request to server
Map<String, dynamic> requestBody = {
'device_id': _deviceDetails.deviceID
};
http.Response response = await http
.post(Uri.parse(Constants.LOGIN_ENDPOINT), body: requestBody);
_user = userFromJson(response.body);
_deviceDetails.userID = _user.data!.userId!;
_deviceDetails.userName = _user.data!.name!;
_deviceDetails.token = _user.data!.token!;
await _saveLoginDetails(_deviceDetails);
print("[INFO] USER LOGGED IN SUCCESSFULLY");
}
} catch (error) {
print("[INFO] ERROR WHILE FETCHING DEVICE DETAILS: $error");
}
} else {
print("[INFO] THIS USER DEVICE IS ALREADY LOGGED IN");
print("[INFO] FETCHING EXISTING USER DETAILS");
Map<String, dynamic> requestBody = {'device_id': _deviceDetails.deviceID};
http.Response response = await http
.post(Uri.parse(Constants.LOGIN_ENDPOINT), body: requestBody);
_user = userFromJson(response.body);
print("INSIDE LOGIN FUNCTION: ${_user.data!.categoryList!.length}"); // prints 2 in console (correct)
}
_isLoading = false;
notifyListeners();
}
控制台输出:
应用首次加载或热重启时的输出:
I/flutter ( 3495): INITIAL: true
I/flutter ( 3495): INITIAL: 1
I/flutter ( 3495): [INFO] THIS USER DEVICE IS ALREADY LOGGED IN
I/flutter ( 3495): [INFO] FETCHING EXISTING USER DETAILS
I/flutter ( 3495): INSIDE LOGIN FUNCTION: 2
应用热重载时的输出 (Ctrl+S):
I/flutter ( 3495): INITIAL: false
I/flutter ( 3495): INITIAL: 2
I/flutter ( 3495): INSIDE: false
I/flutter ( 3495): INSIDE: 2
I/flutter ( 3495): INSIDE: false
I/flutter ( 3495): INSIDE: 2
如您所见,热重载后,状态会发生变化,但不是没有,这意味着notifyListeners() 在login 函数中的行为不正常?
这里可能有什么问题,我真的很困惑......
任何帮助将不胜感激!
【问题讨论】:
标签: flutter dart flutter-provider