颤振网络 - 避免在应用程序通过浏览器的地址栏以不同的路由启动时启动 initialRoute?



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状态下等待,所以无论您提供什么逻辑,页面都会构建。我有一个解决方案,可能也有一些进步或其他好的解决方案,所以这就是我要使用的。

我会用一个未来建设者的概念。它要做的就是等待我的服务器,然后构建整个应用程序。

所以这个过程就是

  1. 在您的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这样的状态管理解决方案。

最新更新