flutter-web-앱이 브라우저의 주소 표시 줄을 통해 다른 경로로 시작될 때 initialRoute가 시작되지 않도록 하시겠습니까?
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 초 후에 앱이 다른 메모 화면을 엽니 다.
어떤 아이디어?
답변
첫 번째 렌더링은 항상 루트 '/'에서 시작되었으므로 스플래시 화면에 대해 고유 한 경로를 사용하는 것이 좋습니다.
initialRoute: '/splash'
.
주소 표시 줄에이 경로를 숨기려면 대체 경로가 경로 생성기지도 :
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
인증 상태를보다 깔끔하게 처리하는 방법
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와 같은 상태 관리 솔루션을 사용해야합니다.