Flutter新手。
我正在制作一个应用程序,它有一个初始屏幕,当用户打开该应用程序时会显示出来。3秒钟后,应用程序将显示登录信息或仪表板屏幕,具体取决于身份验证状态。
这是我的密码。
main.dart
void main() {
runApp(myApp);
}
MaterialApp myApp = MaterialApp(
initialRoute: "/",
routes: {
"/": (context) => SplashScreen(),
"/signin": (context) => SignInScreen(),
"/notes": (context) => NotesScreen(),
},
);
防溅屏.飞镖
class SplashScreen extends StatefulWidget {
@override
_SplashScreenState createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
@override
void initState() {
super.initState();
_goToNextScreen();
}
void _goToNextScreen() {
Future.delayed(
Duration(seconds:3),
() async {
AuthState authState = await Auth.getAuthState();
String route = authState == AuthState.SIGNED_IN ? "/notes" : "/signin";
Navigator.pushReplacementNamed(context, route);
}
);
}
// build() override goes here...
}
我一直在用网络服务器调试这个应用程序。当应用程序以url localhost:8000/启动时,一切似乎都很好。然而,如果应用程序以URLlocalhost:8000/notes启动,我认为启动屏幕仍然会启动。发生的情况是,应用程序将显示笔记屏幕,然后在3秒钟后,应用程序会打开另一个笔记屏幕。
有什么想法吗?
因为第一次渲染总是从根'/'开始,所以最好使用自己的启动屏幕路径,比如
CCD_ 1。
要在地址栏中隐藏此路径,请将路由映射替换为路由生成器:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
onGenerateRoute: (RouteSettings settings) {
// print current route for clarity.
print('>>> ${settings.name} <<<');
switch (settings.name) {
case '/splash':
return MaterialPageRoute(
builder: (context) => SplashScreen(),
// settings omitted to hide route name
);
case '/signin':
return MaterialPageRoute(
builder: (context) => SignInScreen(),
settings: settings,
);
case '/notes':
return MaterialPageRoute(
builder: (context) => NotesScreen(),
settings: settings,
);
case '/':
// don't generate route on start-up
return null;
default:
return MaterialPageRoute(
builder: (context) => FallbackScreen(),
);
}
},
initialRoute: '/splash',
);
}
}
由于主要逻辑是,我们不能在init状态下等待,所以无论您提供什么逻辑,页面都会构建。我有一个解决方案,可能也有一些进步或其他好的解决方案,所以这就是我要使用的。
我会用一个未来建设者的概念。它要做的就是等待我的服务器,然后构建整个应用程序。
所以这个过程就是
-
在您的main.dart中使用
Future<void> main() async { try { WidgetsFlutterBinding.ensureInitialized(); //await for my server code and according to the variable I get I will take action //I would have a global parameter lets say int InternetOff await checkServer(); runApp(MyApp()); } catch (error) { print(error); print('Locator setup has failed'); //I can handle the error here } }
现在MyApp无状态小工具,它将帮助我们选择的路径
class MyApp extends Stateless Widget{
Widget build(BuildContext context) {
//Using this FutureBuilder
return FutureBuilder<String>(
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
// AsyncSnapshot<Your object type>
// Now if InternetOff is equal to one I would make it go to home
if(InternetOff==1) return MaterialApp(
theme: ThemeData.light(),
home: CheckInternet(),
debugShowCheckedModeBanner: false,
);
//else go to Home similarly with these if and else you can add more conditions
else {
return MaterialApp(
theme: ThemeData.dark(),
home: UserHome(),
debugShowCheckedModeBanner: false,
);
}
}
}
},
);
}
}
首先,flutter web和其他任何单页应用程序一样支持基于哈希的路由。因此,如果您想访问
localhost:8000/notes
您必须将其作为访问
localhost:8000/#/notes
处理身份验证状态的更干净的方法
在运行应用程序((之前调用getAuthState函数,以确保在初始化应用程序之前设置了身份验证状态。并将authState作为参数传递给SplashScreen小部件。
void main() {
WidgetsFlutterBinding.ensureInitialized();
AuthState authState = await Auth.getAuthState();
runApp(MaterialApp myApp = MaterialApp(
initialRoute: "/",
routes: {
"/": (context) => SplashScreen(authState: authState),
"/signin": (context) => SignInScreen(),
"/notes": (context) => NotesScreen(),
},
));
}
防溅屏.飞镖
class SplashScreen extends StatefulWidget {
final AuthState authState;
SplashScreen({Key key, this.authState}) : super(key: key);
@override
_SplashScreenState createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
@override
void initState() {
super.initState();
_goToNextScreen();
}
void _goToNextScreen() {
Future.delayed(
Duration(seconds:3),
() async {
String route = widget.authState == AuthState.SIGNED_IN ? "/notes" : "/signin";
Navigator.pushReplacementNamed(context, route);
}
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
);
}
}
如果您想要更干净的方式来处理身份验证状态,您必须使用像Provider这样的状态管理解决方案。