flutter-web - 当应用程序通过浏览器的地址栏以不同的路线启动时,避免启动 initialRoute?
flutter-web - Avoid initialRoute from initiating when the app launched with a different route via the browser's address bar?
Flutter 新手。
我正在制作一个应用程序,它有一个启动画面,当用户打开应用程序时,该画面最初会出现。 3 秒后,应用程序将显示登录或仪表板屏幕,具体取决于身份验证状态。
这是我的代码。
main.dart
void main() {
runApp(myApp);
}
MaterialApp myApp = MaterialApp(
initialRoute: "/",
routes: {
"/": (context) => SplashScreen(),
"/signin": (context) => SignInScreen(),
"/notes": (context) => NotesScreen(),
},
);
splash_screen.dart
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/ 启动时,一切似乎都很好。但是,如果应用程序以 url localhost:8000/notes 启动,我认为启动画面仍会启动。发生的事情是应用程序将显示笔记屏幕,然后 3 秒后,应用程序将打开另一个笔记屏幕。
有什么想法吗?
因为主要逻辑是我们不能在初始状态等待,所以无论您提供什么逻辑,页面都会构建。我有办法解决这个问题,可能还有一些先进的或其他好的解决方案,所以这就是我会用的。
我会使用未来建设者的概念。它会做的是等待我的服务器,然后构建整个应用程序。
所以流程是
在你的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,
);
}
}
}
},
);
}
}
因为第一次渲染总是从根目录“/”开始,所以最好使用您自己的启动画面路径,例如
initialRoute: '/splash'
.
要在地址栏中隐藏此路径,请将 routes 映射替换为路由生成器:
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',
);
}
}
首先,flutter-web 像任何其他单页应用程序一样支持基于哈希的路由。因此,如果您想访问
localhost:8000/notes
您必须以
的身份访问它
localhost:8000/#/notes
处理身份验证状态的更简洁方法
在 runApp() 之前调用 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(),
},
));
}
splash_screen.dart
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 这样的状态管理解决方案。
Flutter 新手。
我正在制作一个应用程序,它有一个启动画面,当用户打开应用程序时,该画面最初会出现。 3 秒后,应用程序将显示登录或仪表板屏幕,具体取决于身份验证状态。
这是我的代码。
main.dart
void main() {
runApp(myApp);
}
MaterialApp myApp = MaterialApp(
initialRoute: "/",
routes: {
"/": (context) => SplashScreen(),
"/signin": (context) => SignInScreen(),
"/notes": (context) => NotesScreen(),
},
);
splash_screen.dart
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/ 启动时,一切似乎都很好。但是,如果应用程序以 url localhost:8000/notes 启动,我认为启动画面仍会启动。发生的事情是应用程序将显示笔记屏幕,然后 3 秒后,应用程序将打开另一个笔记屏幕。
有什么想法吗?
因为主要逻辑是我们不能在初始状态等待,所以无论您提供什么逻辑,页面都会构建。我有办法解决这个问题,可能还有一些先进的或其他好的解决方案,所以这就是我会用的。
我会使用未来建设者的概念。它会做的是等待我的服务器,然后构建整个应用程序。
所以流程是
在你的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,
);
}
}
}
},
);
}
}
因为第一次渲染总是从根目录“/”开始,所以最好使用您自己的启动画面路径,例如
initialRoute: '/splash'
.
要在地址栏中隐藏此路径,请将 routes 映射替换为路由生成器:
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',
);
}
}
首先,flutter-web 像任何其他单页应用程序一样支持基于哈希的路由。因此,如果您想访问
localhost:8000/notes
您必须以
的身份访问它localhost:8000/#/notes
处理身份验证状态的更简洁方法
在 runApp() 之前调用 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(),
},
));
}
splash_screen.dart
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 这样的状态管理解决方案。