前言
Hi, 今天就是把之前寫的一堆功能放到Screen裡面,由於是UI的部分所以程式碼會很長,有些地方我只會擷取片段,建議大家看完整程式碼。
完整程式碼
需要具備知識
Splash Screen
把首頁的MultiBlocProvider加上AuthenticationBloc,並觸發事件AppStarted()來檢查是否有登入過。
1 2 3 4 5 6 7
|
BlocProvider( create: (context) => AuthenticationBloc( authRepository: authRepository, )..add(AppStarted()), ),
|
把這個畫面設置成初始畫面,然後當事件觸發後BlocListener會監聽AuthenticationBloc現在的狀態進行頁面切換。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class SplashScreen extends StatelessWidget { const SplashScreen({Key? key}) : super(key: key);
@override Widget build(BuildContext context) { return BlocListener<AuthenticationBloc, AuthenticationState>( listener: (context, state) { if (state is Unauthenticated) { context.replaceRoute(LoginScreen()); } if (state is Authenticated) { context.replaceRoute(HomeScreen()); } }, child: Scaffold( backgroundColor: Theme.of(context).backgroundColor, ), ); } }
|
Login Screen
在LoginScreen
這邊一樣加一個AuthenticationBloc
監聽器,檢查是否登入成功取得驗證。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| class LoginScreen extends StatelessWidget { const LoginScreen({Key? key}) : super(key: key);
@override Widget build(BuildContext context) { return BlocListener<AuthenticationBloc, AuthenticationState>( listener: (context, state) { if (state is Authenticated) { context.replaceRoute(HomeScreen()); } }, child: Scaffold( backgroundColor: Theme.of(context).backgroundColor, body: Container( width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height, child: Stack( alignment: Alignment.center, children: [ Positioned( top: 200, child: Text( "Hello", style: Theme.of(context).textTheme.bodyText1, ), ), Positioned( top: 370, child: BlocProvider( create: (context) => SignInBloc(authRepository: AuthRepository()), child: LoginFrom(), ), ), ], ), ), ), ); } }
|
Login From
創建SignInBloc
然後在LoginForm
裡面寫一個SignInBloc
的監聽器來檢查登入成功或失敗,如果登入成功的話就觸法LoggedIn
的事件。
1 2 3 4 5 6 7 8
| Positioned( top: 370, child: BlocProvider( create: (context) => SignInBloc(authRepository: AuthRepository()), child: LoginFrom(), ), ),
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class LoginFrom extends StatelessWidget { const LoginFrom({Key? key}) : super(key: key);
@override Widget build(BuildContext context) { return BlocListener<SignInBloc, SignInState>( listener: (context, state) { if (state is SignInStateSuccess) { BlocProvider.of<AuthenticationBloc>(context).add(LoggedIn()); } if (state is SignInStateFailure) { } }, child: Column( children: [ GoogleSignInButton(), ], ), ); } }
|
Home Screen
在首頁檢查驗證登入狀態,然後在登出按鈕(左上角的小啤酒)新增LoggedOut事件。
1 2 3 4 5 6
| return BlocListener<AuthenticationBloc, AuthenticationState>( listener: (context, state) { if (state is Unauthenticated) { context.replaceRoute(LoginScreen()); } },
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class SignOutButton extends StatelessWidget { @override Widget build(BuildContext context) { return IconButton( onPressed: () { BlocProvider.of<AuthenticationBloc>(context).add(LoggedOut()); }, icon: Icon( Icons.sports_bar_rounded, color: Theme.of(context).shadowColor, size: 30, ), ); } }
|