如何在 Flutter 中将两个屏幕之一正确导航给用户?
How to Navigate one of the two screens to users correctly in Flutter?
最近我正在用 Flutter 开发第一个应用程序,我只知道基础知识。
这就是我目前面临的问题。
我必须根据 old/new 用户导航两个屏幕之一,注册或主页,所以我所做的就是这里。
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'Register.dart';
import 'HomePage.dart';
class Authenticate extends StatefulWidget {
@override
_AuthenticateState createState() => _AuthenticateState();
}
class _AuthenticateState extends State<Authenticate> {
String _userName = "";
@override
void initState() {
super.initState();
_getUserName();
}
_getUserName() async {
SharedPreferences pref = await SharedPreferences.getInstance();
setState(() {
_userName = pref.getString('userName') ?? "";
});
}
Widget build(BuildContext context) {
if (_userName == "") {
print('name : $_userName , NEW user'); // ERROR - why it's printing on console for old User ?
return Register();
} else {
return HomePage(_userName);
}
}
}
所以问题是,即使我通过老用户打开应用程序,它也会打印为新用户编写的调试代码,注册屏幕的屏幕可见性约为 0.3 秒。
那么我应该怎么做才能解决这个问题?
正在打印,因为这行代码:
SharedPreferences pref = await SharedPreferences.getInstance();
是异步的,这意味着它可能会在稍后的某个时间点调用。因为 build
方法首先被调用,然后你的 _getUserName
方法完成,这导致 setState
并再次调用 build
方法。
您可能希望在初始化 sharedPrefernces 之前显示某种加载程序屏幕,然后决定是否显示 Register
或 Home
页面。
示例代码:
class _AuthenticateState extends State<Authenticate> {
String _userName = "";
bool _isLoading = true;
@override
void initState() {
super.initState();
_getUserName();
}
_getUserName() async {
SharedPreferences pref = await SharedPreferences.getInstance();
setState(() {
_userName = pref.getString('userName') ?? "";
_isLoading = false;
});
}
Widget build(BuildContext context) {
if (_isLoading) {
return Center(child: CupertinoActivityIndicator());
} else if (_userName == "") {
print('name : $_userName , NEW user'); // ERROR - why it's printing on console for old User ?
return Register();
} else {
return HomePage(_userName);
}
}
}
试试这个:
class _AuthenticateState extends State<Authenticate> {
String _userName;
@override
void initState() {
super.initState();
_getUserName();
}
_getUserName() async {
SharedPreferences pref = await SharedPreferences.getInstance();
setState(() {
_userName = pref.getString('userName') ?? '';
});
}
Widget build(BuildContext context) {
if (_userName == null) {
return Center(child: CircularProgressIndicator());
} else if (_userName == '') {
print('name : $_userName , NEW user');
return Register();
} else {
return HomePage(_userName);
}
}
}
在这种情况下,_userName
最初是 null
,并且只会在 _getUserName()
return 之后分配一个空字符串或旧用户名。当为 null 时,小部件将构建一个进度指示器。如果你不想这样,只需 return a Container()
.
最近我正在用 Flutter 开发第一个应用程序,我只知道基础知识。 这就是我目前面临的问题。
我必须根据 old/new 用户导航两个屏幕之一,注册或主页,所以我所做的就是这里。
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'Register.dart';
import 'HomePage.dart';
class Authenticate extends StatefulWidget {
@override
_AuthenticateState createState() => _AuthenticateState();
}
class _AuthenticateState extends State<Authenticate> {
String _userName = "";
@override
void initState() {
super.initState();
_getUserName();
}
_getUserName() async {
SharedPreferences pref = await SharedPreferences.getInstance();
setState(() {
_userName = pref.getString('userName') ?? "";
});
}
Widget build(BuildContext context) {
if (_userName == "") {
print('name : $_userName , NEW user'); // ERROR - why it's printing on console for old User ?
return Register();
} else {
return HomePage(_userName);
}
}
}
所以问题是,即使我通过老用户打开应用程序,它也会打印为新用户编写的调试代码,注册屏幕的屏幕可见性约为 0.3 秒。
那么我应该怎么做才能解决这个问题?
正在打印,因为这行代码:
SharedPreferences pref = await SharedPreferences.getInstance();
是异步的,这意味着它可能会在稍后的某个时间点调用。因为 build
方法首先被调用,然后你的 _getUserName
方法完成,这导致 setState
并再次调用 build
方法。
您可能希望在初始化 sharedPrefernces 之前显示某种加载程序屏幕,然后决定是否显示 Register
或 Home
页面。
示例代码:
class _AuthenticateState extends State<Authenticate> {
String _userName = "";
bool _isLoading = true;
@override
void initState() {
super.initState();
_getUserName();
}
_getUserName() async {
SharedPreferences pref = await SharedPreferences.getInstance();
setState(() {
_userName = pref.getString('userName') ?? "";
_isLoading = false;
});
}
Widget build(BuildContext context) {
if (_isLoading) {
return Center(child: CupertinoActivityIndicator());
} else if (_userName == "") {
print('name : $_userName , NEW user'); // ERROR - why it's printing on console for old User ?
return Register();
} else {
return HomePage(_userName);
}
}
}
试试这个:
class _AuthenticateState extends State<Authenticate> {
String _userName;
@override
void initState() {
super.initState();
_getUserName();
}
_getUserName() async {
SharedPreferences pref = await SharedPreferences.getInstance();
setState(() {
_userName = pref.getString('userName') ?? '';
});
}
Widget build(BuildContext context) {
if (_userName == null) {
return Center(child: CircularProgressIndicator());
} else if (_userName == '') {
print('name : $_userName , NEW user');
return Register();
} else {
return HomePage(_userName);
}
}
}
在这种情况下,_userName
最初是 null
,并且只会在 _getUserName()
return 之后分配一个空字符串或旧用户名。当为 null 时,小部件将构建一个进度指示器。如果你不想这样,只需 return a Container()
.