最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Flutter狀態(tài)管理Bloc之登錄示例

 更新時間:2022年03月24日 10:35:11   作者:mazaiting  
這篇文章主要為大家詳細介紹了Flutter狀態(tài)管理Bloc之登錄示例,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文實例為大家分享了Flutter狀態(tài)管理Bloc之登錄的具體代碼,供大家參考,具體內容如下

1. 依賴

dependencies:
? flutter_bloc: ^2.1.1
? equatable: ^1.0.1

2. UserRepository 用于管理用戶數據

提供認證方法,刪除Token,保存Token,是否包含Token四個方法。

import 'package:flutter/material.dart';
?
/// 用戶數據倉庫
class UserRepository {
?
? /// 認證
? /// @param username 用戶名
? /// @param password 密碼
? /// @return 返回認證信息
? Future<String> authenticate({
? ? @required String username,
? ? @required String password,
? }) async {
? ? await Future.delayed(Duration(seconds: 1));
? ? return "token";
? }
?
? /// 刪除Token
? Future<void> deleteToToken() async {
? ? await Future.delayed(Duration(seconds: 1));
? ? return ;
? }
?
? /// 保存Token
? /// @param token 令牌
? Future<void> persistToken(String token) async {
? ? // 保存
? ? await Future.delayed(Duration(seconds: 1));
? ? return ;
? }
?
? /// 判斷是否有Token
? /// @return true: 有; false: 沒有Token
? Future<bool> hasToken() async {
? ? // 讀取Token
? ? await Future.delayed(Duration(seconds: 1));
? ? return false;
? }
}

3. AuthenticateState

  • uninitialized - 身份驗證未初始化
  • loading - 等待保存/刪除Token
  • authenticated - 認證成功
  • unauthenticated - 未認證
import 'package:equatable/equatable.dart';
?
/// 認證狀態(tài)
abstract class AuthenticationState extends Equatable {
? @override
? List<Object> get props => [];
}
?
/// - uninitialized - 身份驗證未初始化
class AuthenticationUninitialized extends AuthenticationState {}
/// - loading - 等待保存/刪除Token
class AuthenticationLoading extends AuthenticationState {}
/// - authenticated - 認證成功
class AuthenticationAuthenticated extends AuthenticationState {}
/// - unauthenticated - 未認證
class AuthenticationUnauthenticated extends AuthenticationState {}

4. 認證事件

  • AppStarted - App 啟動事件
  • LoggedIn - 登錄事件
  • LoggedOut - 退出登錄事件
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
?
/// 認證事件
abstract class AuthenticationEvent extends Equatable {
?
? const AuthenticationEvent();
?
? @override
? List<Object> get props => [];
?
}
?
/// APP 啟動事件
class AppStart extends AuthenticationEvent {}
?
/// APP 登錄事件
class LoginIn extends AuthenticationEvent {
??
? final String token;
?
? const LoginIn({@required this.token});
?
? @override
? List<Object> get props => [token];
?
? @override
? String toString() => "LoggedIn { token: $token }";
}
?
/// APP 退出登錄事件
class LoginOut extends AuthenticationEvent {}

5. AuthenticationBloc

  • 實現構造方法
  • 實現initialState方法
  • 實現mapEventToState方法
import 'package:bloc/bloc.dart';
import 'package:flutter/material.dart';
import './bloc.dart';
import 'package:state_manage/login/user_repository.dart';
?
/// 認證Bloc
class AuthenticationBloc extends Bloc<AuthenticationEvent, AuthenticationState> {
? // 用戶倉庫
? final UserRepository userRepository;
?
? AuthenticationBloc({@required this.userRepository}): assert(userRepository != null);
?
? @override
? AuthenticationState get initialState => AuthenticationUninitialized();
?
? @override
? Stream<AuthenticationState> mapEventToState(AuthenticationEvent event) async* {
? ? if (event is AppStarted) {
? ? ? // 判斷是否有Token
? ? ? final bool hasToken = await userRepository.hasToken();
? ? ? if (hasToken) {
? ? ? ? yield AuthenticationAuthenticated();
? ? ? } else {
? ? ? ? yield AuthenticationUnauthenticated();
? ? ? }
? ? } else if (event is LoggedIn) {
? ? ? yield AuthenticationLoading();
? ? ? await userRepository.persistToken(event.token);
? ? ? yield AuthenticationAuthenticated();
? ? } else if (event is LoggedOut) {
? ? ? yield AuthenticationLoading();
? ? ? await userRepository.deleteToToken();
? ? ? yield AuthenticationUnauthenticated();
? ? }
? }
}

6. SplashPage 啟動頁

import 'package:flutter/material.dart';
?
/// 啟動頁
class SplashPage extends StatelessWidget {
? @override
? Widget build(BuildContext context) {
? ? return Scaffold(
? ? ? body: Center(
? ? ? ? child: Text('Splash Screen'),
? ? ? ),
? ? );
? }
}

7. HomePage 主頁

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:state_manage/login/bloc/bloc.dart';
?
/// 主頁
class HomePage extends StatelessWidget {
? @override
? Widget build(BuildContext context) {
? ? return Scaffold(
? ? ? appBar: AppBar(
? ? ? ? title: Text('Home'),
? ? ? ),
? ? ? body: Container(
? ? ? ? child: Center(
? ? ? ? ? child: RaisedButton(
? ? ? ? ? ? child: Text('logout'),
? ? ? ? ? ? onPressed: () => BlocProvider.of<AuthenticationBloc>(context).add(LoggedOut())
? ? ? ? ? ),
? ? ? ? ),
? ? ? ),
? ? );
? }
}

8. LoginState 登錄狀態(tài)

  • LoginInitial - 初始化狀態(tài)
  • LoginLoading - 登錄中狀態(tài)
  • LoginFailure - 登錄失敗狀態(tài)
import 'package:equatable/equatable.dart';
import 'package:meta/meta.dart';
?
/// 登錄狀態(tài)
@immutable
abstract class LoginState extends Equatable {
? const LoginState();
?
? @override
? List<Object> get props => [];
}
??
/// 登錄初始化狀態(tài)
class LoginInitial extends LoginState {}
?
/// 正在登錄中狀態(tài)
class LoginLoading extends LoginState {}
?
/// 登錄失敗狀態(tài)
class LoginFailure extends LoginState {
? final String error;
?
? const LoginFailure({@required this.error});
?
? @override
? List<Object> get props => [error];
?
? @override
? String toString() => "LoginFailure { error: $error }";
}

9. LoginEvent 登錄事件

import 'package:equatable/equatable.dart';
import 'package:meta/meta.dart';
?
/// 登錄事件
@immutable
abstract class LoginEvent extends Equatable{}
?
/// 登錄事件
class LoginPressed extends LoginEvent {
? /// 用戶名
? final String username;
? /// 密碼
? final String password;
?
? LoginPressed({
? ? @required this.username,
? ? @required this.password
? });
?
? @override
? List<Object> get props => [username, password];
?
? @override
? String toString() => "LoginPressed { username: $username, password: $password }";
}

10. LoginBloc 實現

import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:flutter/cupertino.dart';
import 'package:state_manage/login/user_repository.dart';
import './bloc.dart';
?
class LoginBloc extends Bloc<LoginEvent, LoginState> {
? /// 用戶信息倉庫
? final UserRepository userRepository;
?
? /// 認證Bloc
? final AuthenticationBloc authenticationBloc;
?
? LoginBloc({@required this.userRepository, @required this.authenticationBloc})
? ? ? : assert(userRepository != null),
? ? ? ? assert(authenticationBloc != null);
?
? @override
? LoginState get initialState => LoginInitial();
?
? @override
? Stream<LoginState> mapEventToState(
? ? LoginEvent event,
? ) async* {
? ? if (event is LoginPressed) {
? ? ? yield LoginLoading();
?
? ? ? try {
? ? ? ? final token = await userRepository.authenticate(
? ? ? ? ? username: event.username,
? ? ? ? ? password: event.password
? ? ? ? );
? ? ? ? authenticationBloc.add(LoggedIn(token: token));
? ? ? ? yield LoginInitial();
? ? ? } catch (error) {
? ? ? ? yield LoginFailure(error: error);
? ? ? }
? ? }
? }
}

11. 登錄頁面

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:state_manage/login/bloc/bloc.dart';
import 'package:state_manage/login/user_repository.dart';
?
/// 登錄頁面
class LoginPage extends StatelessWidget {
? /// 用戶信息倉庫
? final UserRepository userRepository;
?
? LoginPage({Key key, @required this.userRepository})
? ? ? : assert(userRepository != null),
? ? ? ? super(key: key);
?
? @override
? Widget build(BuildContext context) {
? ? return Scaffold(
? ? ? appBar: AppBar(
? ? ? ? title: Text('Login'),
? ? ? ),
? ? ? body: BlocProvider(
? ? ? ? create: (ctx) => LoginBloc(
? ? ? ? ? ? authenticationBloc: BlocProvider.of(context),
? ? ? ? ? ? userRepository: userRepository),
? ? ? ? child: LoginForm(),
? ? ? ),
? ? );
? }
}
?
/// 登錄表單
class LoginForm extends StatefulWidget {
? @override
? State<StatefulWidget> createState() => _LoginFormState();
}
?
/// 登錄狀態(tài)表單
class _LoginFormState extends State<LoginForm> {
? /// 用戶名控制器
? final _usernameController = TextEditingController();
?
? /// 密碼控制器
? final _passwordController = TextEditingController();
? @override
? Widget build(BuildContext context) {
? ? _onLoginPressed() {
? ? ? BlocProvider.of<LoginBloc>(context).add(LoginPressed(
? ? ? ? ? username: _usernameController.text,
? ? ? ? ? password: _passwordController.text));
? ? }
?
? ? return BlocListener<LoginBloc, LoginState>(
? ? ? listener: (ctx, state) {
? ? ? ? if (state is LoginFailure) {
? ? ? ? ? Scaffold.of(context).showSnackBar(SnackBar(
? ? ? ? ? ? content: Text('${state.error}'),
? ? ? ? ? ? backgroundColor: Colors.red,
? ? ? ? ? ));
? ? ? ? }
? ? ? },
? ? ? child: BlocBuilder<LoginBloc, LoginState>(
? ? ? ? builder: (ctx, state) {
? ? ? ? ? return Form(
? ? ? ? ? ? child: Column(
? ? ? ? ? ? ? children: <Widget>[
? ? ? ? ? ? ? ? TextFormField(
? ? ? ? ? ? ? ? ? decoration: InputDecoration(labelText: 'username'),
? ? ? ? ? ? ? ? ? controller: _usernameController,
? ? ? ? ? ? ? ? ),
? ? ? ? ? ? ? ? TextFormField(
? ? ? ? ? ? ? ? ? decoration: InputDecoration(labelText: 'password'),
? ? ? ? ? ? ? ? ? controller: _passwordController,
? ? ? ? ? ? ? ? ),
? ? ? ? ? ? ? ? RaisedButton(
? ? ? ? ? ? ? ? ? onPressed: state is LoginLoading ? _onLoginPressed : null,
? ? ? ? ? ? ? ? ? child: Text('Login'),
? ? ? ? ? ? ? ? ),
? ? ? ? ? ? ? ? Container(
? ? ? ? ? ? ? ? ? child: state is LoginLoading
? ? ? ? ? ? ? ? ? ? ? ? CircularProgressIndicator()
? ? ? ? ? ? ? ? ? ? ? : null,
? ? ? ? ? ? ? ? )
? ? ? ? ? ? ? ],
? ? ? ? ? ? ),
? ? ? ? ? );
? ? ? ? },
? ? ? ),
? ? );
? }
}

12. 測試頁面

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:state_manage/login/bloc/bloc.dart';
import 'package:state_manage/login/home_page.dart';
import 'package:state_manage/login/login_page.dart';
import 'package:state_manage/login/splash_page.dart';
import 'package:state_manage/login/user_repository.dart';
?
/// 登錄測試頁面
class LoginTest extends StatelessWidget {
? // 數據倉庫
? final userRepository = UserRepository();
?
? @override
? Widget build(BuildContext context) {
? ? return BlocProvider<AuthenticationBloc>(
? ? ? create: (context) =>
? ? ? ? ? AuthenticationBloc(userRepository: userRepository)..add(AppStarted()),
? ? ? child: App(userRepository: userRepository),
? ? );
? }
}
?
/// 應用頁
class App extends StatelessWidget{
? // 數據倉庫
? final UserRepository userRepository;
?
? App({Key key, @required this.userRepository}) : super(key: key);
?
? @override
? Widget build(BuildContext context) {
? ? return MaterialApp(
? ? ? home: BlocBuilder<AuthenticationBloc, AuthenticationState>(
? ? ? ? builder: (context, state) {
? ? ? ? ? if (state is AuthenticationAuthenticated) {
? ? ? ? ? ? return HomePage();
? ? ? ? ? } else if (state is AuthenticationUnauthenticated) {
? ? ? ? ? ? return LoginPage(userRepository: userRepository);
? ? ? ? ? } else if (state is AuthenticationLoading) {
? ? ? ? ? ? return LoadingIndicator();
? ? ? ? ? } else {
? ? ? ? ? ? if (state is AuthenticationUninitialized) {
? ? ? ? ? ? ? return SplashPage();
? ? ? ? ? ? } else {
? ? ? ? ? ? ? return SplashPage();
? ? ? ? ? ? }
? ? ? ? ? }
? ? ? ? },
? ? ? ),
? ? );
? }
?
}
?
/// 加載狀態(tài)
class LoadingIndicator extends StatelessWidget {
? @override
? Widget build(BuildContext context) {
? ? return Scaffold(
? ? ? backgroundColor: Colors.white,
? ? ? body: Center(
? ? ? ? child: CircularProgressIndicator(),
? ? ? ),
? ? );
? }
}

效果圖:

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • Flutter 創(chuàng)建私有公共插件的步驟

    Flutter 創(chuàng)建私有公共插件的步驟

    flutter pub中有很多開源庫,如dio、provider等,這些都是package,直接在pubspec中引入就可以在工程中使用??聪氯绾巫约哼M行創(chuàng)建
    2021-05-05
  • Android實現360手機助手底部的動畫菜單

    Android實現360手機助手底部的動畫菜單

    這篇文章給大家分享了利用Android實現360手機助手底部的動畫菜單效果,文中給出了實例代碼,這樣對大家的學習或者理解更有幫助,有需要的朋友們下面來一起看看吧。
    2016-10-10
  • Android AndBase框架實現多功能標題欄(一)

    Android AndBase框架實現多功能標題欄(一)

    這篇文章主要整理了Android AndBase框架學習筆記,本文主要使用AndBase實現多功能標題欄,感興趣的小伙伴們可以參考一下
    2016-03-03
  • Android 開機應用掃描相關總結

    Android 開機應用掃描相關總結

    本篇文章只是作為指南引導去看PkMS,不會貼大段代碼進行分析,更多是基于方法分析實現的邏輯,另外就是代碼是基于Android 11,與Android 10之前代碼有比較大的差別。
    2021-05-05
  • Android 開發(fā)訂單流程view實例詳解

    Android 開發(fā)訂單流程view實例詳解

    這篇文章主要介紹了 Android 開發(fā)訂單流程view實例詳解的相關資料,需要的朋友可以參考下
    2017-03-03
  • Android studio實現菜單操作

    Android studio實現菜單操作

    這篇文章主要為大家詳細介紹了Android studio實現菜單操作,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • Android實現點擊AlertDialog上按鈕時不關閉對話框的方法

    Android實現點擊AlertDialog上按鈕時不關閉對話框的方法

    這篇文章主要介紹了Android實現點擊AlertDialog上按鈕時不關閉對話框的方法,涉及設置監(jiān)聽的相關技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-02-02
  • Android共享元素動畫效果顯示問題解決

    Android共享元素動畫效果顯示問題解決

    什么是共享元素呢?可以理解為當頁面跳轉是,看起來一個View屬于界面A又屬于界面B,下面這篇文章主要給大家介紹了關于Android共享元素動畫效果顯示問題的相關資料,需要的朋友可以參考下
    2022-02-02
  • Android ProgressDialog用法之實現app上傳文件進度條轉圈效果

    Android ProgressDialog用法之實現app上傳文件進度條轉圈效果

    這篇文章主要介紹了Android ProgressDialog用法之實現app上傳文件進度條轉圈效果,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-03-03
  • Android實現酷炫的頂部欄

    Android實現酷炫的頂部欄

    這篇文章主要為大家詳細介紹了Android實現酷炫的頂部欄,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-09-09

最新評論

富裕县| 旅游| 东港市| 旅游| 营山县| 蒙山县| 额尔古纳市| 葫芦岛市| 前郭尔| 旺苍县| 怀柔区| 吐鲁番市| 罗山县| 和田县| 定远县| 桂东县| 娱乐| 扎兰屯市| 常山县| 南陵县| 卢氏县| 常德市| 雷波县| 武鸣县| 江西省| 慈溪市| 孟村| 贵州省| 四会市| 巴南区| 潜山县| 专栏| 上思县| 大石桥市| 廊坊市| 伽师县| 临沭县| 萨嘎县| 西华县| 会泽县| 吕梁市|