[英]Flutter: How to use GoRouter with Bloc to route from Splash Screen to Login Screen
所以我最近在我的應用程序中切換到 Go 路由器,因為它很容易實現。 但是我無法從初始屏幕移動到登錄屏幕。 我的啟動畫面中有邏輯,我可以在其中檢查用戶是否登錄。 根據用戶的身份驗證,屏幕會轉到登錄屏幕或主頁。
這是啟動畫面。
class SplashScreen extends StatefulWidget {
static const routeName = "/SplashScreen";
const SplashScreen({Key? key}) : super(key: key);
@override
_SplashScreenState createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen>
with SingleTickerProviderStateMixin {
@override
Widget build(BuildContext context) {
return BlocConsumer<AuthenticationBloc, AuthenticationState>(
listener: (context, state) {
if (kDebugMode) {
print('Listener: $state');
}
Future.delayed(const Duration(seconds: 3), () {
if (state.authStatus == AuthStatus.unAuthenticated) {
GoRouter.of(context).go('/login');
Navigator.pushNamed(context, SignUpScreen.routeName);
} else if (state.authStatus == AuthStatus.authenticated) {
//Navigator.popUntil(context, (route) => route.isFirst);
Navigator.pushReplacementNamed(context, HomePage.routeName);
}
});
},
builder: (context, Object? state) {
if (kDebugMode) {
print('object: $state');
}
return Scaffold(
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Text(
"Welcome to Musajjal",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18),
),
const SizedBox(
height: 20,
),
Image.asset(
'assets/musajjalBlue.png',
width: 300,
height: 300,
),
const SizedBox(
height: 20,
),
const Text(
"Hifz ul Quran Records",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18),
),
const SizedBox(
height: 20,
),
const CircularProgressIndicator(
color: Colors.blueGrey,
),
],
),
),
);
},
);
}
}
接下來,這個。 是我的 Go 路由器 function
GoRouter _router(AuthenticationBloc bloc) {
return GoRouter(
routes: <GoRoute>[
GoRoute(
path: '/',
builder: (context, state) => const SplashScreen(),
routes: <GoRoute>[
GoRoute(path: 'login', builder: (context, state) => LoginScreen()),
GoRoute(
path: 'signUp', builder: (context, state) => SignUpScreen()),
GoRoute(path: 'homePage', builder: (context, state) => HomePage())
],
redirect: (BuildContext context, GoRouterState state) {
final isLoggedIn =
bloc.state.authStatus == AuthStatus.authenticated;
final isLoggingIn = state.location == '/login';
print(isLoggedIn);
if (!isLoggedIn && !isLoggingIn) return '/login';
if (isLoggedIn && isLoggingIn) return '/homePage';
return null;
},
),
],
);
}
問題是該應用程序卡在啟動畫面上,並且不會前進到登錄屏幕。 請幫忙。
嘗試將重定向中的邏輯更改為
if (!isLoggedIn && !isLoggingIn) return '/login';
if (isLoggedIn) return '/homePage';
另外,考慮將登錄邏輯作為 OR 而不是 AND --optional
if (!isLoggedIn || !isLoggingIn) return '/login';
試試下面的代碼:
main.dart
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider<AuthenticationBloc>(
create: (context) => AuthenticationBloc), 👈 Specify the BlocProvider here
),
],
child: MaterialApp(
theme: customTheme(context),
debugShowCheckedModeBanner: false,
routerConfig: router,
}
router.dart
final GoRouter router = GoRouter(routes: [
GoRoute(
path: "/",
builder: (context, state) {
return BlocBuilder<AuthCubit, AuthState>(
buildWhen: (oldState, newState) {
return oldState is AuthInitialState;
},
builder: (context, state) {
if (state is AuthLoading) {
// return const SplashScreen(); // alternative way
context.goNamed(SplashScreen.routeName); 👈 Display your splash screen here and you can provide delay while changing state in your bloc
}
else if (state is AuthenticationUnauthenticated) {
context.goNamed(LoginPage.routeName);
} else if (state is Authenticated) {
context.goNamed(HomePage.routeName);
} else {
return const Scaffold();
}
},
);
}),
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.