广告
返回顶部
首页 > 资讯 > 移动开发 >Flutter状态管理Bloc之登录示例
  • 701
分享到

Flutter状态管理Bloc之登录示例

2024-04-02 19:04:59 701人浏览 泡泡鱼
摘要

本文实例为大家分享了Flutter状态管理Bloc之登录的具体代码,供大家参考,具体内容如下 1. 依赖 dependencies:   flutter_bloc: ^2.1.1  

本文实例为大家分享了Flutter状态管理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';
 
/// 认证状态
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 登录状态

  • LoginInitial - 初始化状态
  • LoginLoading - 登录中状态
  • LoginFailure - 登录失败状态
import 'package:equatable/equatable.dart';
import 'package:meta/meta.dart';
 
/// 登录状态
@immutable
abstract class LoginState extends Equatable {
  const LoginState();
 
  @override
  List<Object> get props => [];
}
  
/// 登录初始化状态
class LoginInitial extends LoginState {}
 
/// 正在登录中状态
class LoginLoading extends LoginState {}
 
/// 登录失败状态
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();
}
 
/// 登录状态表单
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();
            }
          }
        },
      ),
    );
  }
 
}
 
/// 加载状态
class LoadingIndicator extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: Center(
        child: CircularProgressIndicator(),
      ),
    );
  }
}

效果图:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。

--结束END--

本文标题: Flutter状态管理Bloc之登录示例

本文链接: https://www.lsjlt.com/news/143720.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Flutter状态管理Bloc之登录示例
    本文实例为大家分享了Flutter状态管理Bloc之登录的具体代码,供大家参考,具体内容如下 1. 依赖 dependencies:   flutter_bloc: ^2.1.1  ...
    99+
    2022-11-13
  • Flutter状态管理Bloc之定时器示例
    本文实例为大家分享了Flutter状态管理Bloc之定时器的具体代码,供大家参考,具体内容如下 1. 依赖 dependencies:   flutter_bloc: ^2.1.1 ...
    99+
    2022-11-13
  • Flutter状态管理Bloc使用示例详解
    目录前言两种使用模式Cubit模式最后前言 目前Flutter三大主流状态管理框架分别是provider、flutter_bloc、getx,三大状态管理框架各有优劣,本篇文章将介绍...
    99+
    2022-11-13
    Flutter状态管理Bloc Flutter Bloc
  • Flutter状态管理Bloc之定时器怎么实现
    小编给大家分享一下Flutter状态管理Bloc之定时器怎么实现,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!具体内容如下1. 依赖dependencies:  flutter_bloc: ^...
    99+
    2023-06-29
  • Flutter状态管理Provider示例解析
    目录什么是状态管理常见的状态管理框架有哪些ProviderReduxGetXProvider 使用添加依赖导入应用定义需要共享的数据在应用程序入口初始化使用共享数据状态管理的好处结束...
    99+
    2022-12-08
    Flutter状态管理Provider Flutter Provider
  • Flutter状态管理Provider的使用示例详解
    目录前言计数器全局状态总结前言 Provider是三大主流状态管理框架官方推荐使用的框架,它是基于官方数据共享组件InheritedWidget实现的,通过数据改变调用生命周期中的d...
    99+
    2022-11-13
    Flutter状态管理Provider Flutter Provider
  • java之Hibernate状态整理的示例分析
    这篇文章主要介绍了java之Hibernate状态整理的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。Java有哪些集合类Java中的集合主要分为四类:1、List列...
    99+
    2023-06-14
  • vuex状态管理模式的示例分析
    小编给大家分享一下vuex状态管理模式的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、前言本次接受一个BI系统,要求...
    99+
    2022-10-19
  • vuex项目中登录状态管理的实践过程
    目录工具: 登录场景: 实践: 场景1思考与实践 场景2思考与实践 总结工具: chorme浏览器安装Vue.js devtools方便调试 登录场景: 页面的导航处或其他地方有...
    99+
    2022-11-12
  • 如何使用Redis实现用户登录状态管理
    《如何使用Redis实现用户登录状态管理,需要具体代码示例》  Redis是一种开源的内存数据库,它被广泛应用于缓存、会话管理和消息队列等领域。在Web开发中,用户登录状态管理是一个非常重要的功能,而Redis正是一个很好的选择来实现这一功...
    99+
    2023-11-09
    redis 用户 登录状态
  • vuejs中vuex状态管理模式的示例分析
    这篇文章给大家分享的是有关vuejs中vuex状态管理模式的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。关于vuex类的新闻最近很多,看到眼热就去查了下资料,然后扯出来...
    99+
    2022-10-19
  • Vue 2.X中状态管理vuex的示例分析
    这篇文章将为大家详细讲解有关Vue 2.X中状态管理vuex的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。示例:记住上述的顺序情况:想要改变state,只能通过...
    99+
    2022-10-19
  • vue中状态管理模式vuex的示例分析
    这篇文章主要介绍了vue中状态管理模式vuex的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。vuex是一个专门为vue.js设计的...
    99+
    2022-10-19
  • React 状态管理工具优劣势示例分析
    目录什么是状态管理React 状态管理方案方案介绍方案对比Source相关建议什么是状态管理 “状态”是描述应用程序当前行为的任何数据。这可能包括诸如&ld...
    99+
    2023-01-13
    React 状态管理工具优劣势 React 状态管理工具
  • Vue3中Vuex状态管理学习实战示例详解
    目录引言一、目录结构二、版本依赖三、配置Vuex四、使用Vuex引言 Vuex 是 Vue 全家桶重要组成之一,专为 Vue.js 应用程序开发的 状态管理模式 + 库 ,它采用集中...
    99+
    2022-11-13
  • 小程序中用户登录状态检查与更新的示例分析
    这篇文章主要介绍小程序中用户登录状态检查与更新的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!将这个部分单独作为一篇文章有两个原因:① wx.getUserInfo...
    99+
    2022-10-19
  • vue前端开发辅助函数状态管理详解示例
    目录mapStatemapGettersmapMutationsmapActions示例小结mapState 当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些重复和冗...
    99+
    2022-11-12
  • phpmyadmin管理数据记录之插入数据的示例
    这篇文章主要介绍phpmyadmin管理数据记录之插入数据的示例,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!插入数据选择某个数据表后,单击超链接,进入插入数据界面。在界面中输入各字...
    99+
    2022-10-18
  • vue组件化开发种vuex状态管理库的示例分析
    这篇文章主要介绍vue组件化开发种vuex状态管理库的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中...
    99+
    2022-10-19
  • 基于ReactContext实现一个简单的状态管理的示例代码
    目录前言封装一个父组件用来包裹其他子组件子组件如何获取数据呢class Component 方式context.ConsumeruseContext总结参考前言 在大多数情况下,我们...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作