BLoC Pattern Event In Flutter

BLoC Pattern Event In Flutter :

This flutter tutorial post is BLoC pattern event in flutter.

Screenshot :

BLoC Patte Event In Flutter

BLoC Patte Event In Flutter

BLoC Patte Event In Flutter

BLoC Patte Event In Flutter

BLoC Patte Event In Flutter

BLoC Patte Event In Flutter

blocs package contain 4 packages

blocs package

  • login
  • promoter
  • user : Login successfull after save the data. For example username, email etc.
  • viewmodel : Constant data save. For example List.
  • common_state.dart : Check the Api call or not

Every bloc pattern 3 class contains
1) state
2) event
3) bloc

For example:

Login state

  • username, password is input.
  • loading, loaded, error api call to response

Login event

  • input username, password
  • callback get the from api

Login bloc

  • userNameInput, passwordInput input data.
  • login is call user press button login then. That is call login_page.dart onRegisterDevice().

pubspec.yaml

yaml file use to flutter name and decscription of application, sdk version, dependencies, assets, fonts.

This application 6 dependencies add
1) cupertino_icons: ^0.1.2
2) shared_preferences:
3) intl:
4) font_awesome_flutter:
5) flutter_bloc:
6) provider:

pubspec.yaml

name: block_pattern_event
description: A new Flutter application.

version: 1.0.0+1

environment:
  sdk: ">=2.5.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter

  cupertino_icons: ^0.1.2
  shared_preferences:
  intl:
  font_awesome_flutter:
  flutter_bloc:
  provider:

dev_dependencies:
  flutter_test:
    sdk: flutter

flutter:
  uses-material-design: true

  assets:
    - assets/images/

  fonts:
    - family: Quicksand
      fonts:
        - asset: assets/fonts/quicksand_medium.ttf
          style: normal
        - asset: assets/fonts/quicksand_bold.otf
          weight: 700


    - family: Raleway
      fonts:
        - asset: assets/fonts/raleway_regular.ttf
          style: normal
        - asset: assets/fonts/raleway_medium.ttf

BLoC Package :

– Login Package :

login_bloc.dart

import 'package:bloc/bloc.dart';
import 'package:block_pattern_event/models/login.dart';
import 'login_event.dart';
import 'login_state.dart';

class LoginBloc extends Bloc<LoginEvent, LoginState> {

  void userNameInput(mobileEmail) {
    dispatch(UserNameInput(username: mobileEmail));
  }

  void passwordInput(passwordInput) {
    dispatch(PasswordInput(password: passwordInput));
  }

  void login(callback) {
    dispatch(Login(callback: callback));
  }

  @override
  LoginState get initialState => LoginState.initial();

  @override
  Stream<LoginState> mapEventToState(LoginEvent event) async* {
    if (event is UserNameInput) {
      yield currentState.copyWith(username: event.username);
    }

    if (event is PasswordInput) {
      yield currentState.copyWith(password: event.password);
    }

    if (event is Login) {
      yield currentState.copyWith(loading: true);

      try {
        yield currentState.copyWith(
          loaded: true,
          loading: false,
          error: {},
        );
        event.callback(new LoginResponse(
            mobile: '',
            id: 1,
            code: '200',
            firstName: 'admin',
            lastName: 'admin',
            username: 'Flutter Tutorial'));
      } catch (e) {
        yield currentState.copyWith(
          loaded: true,
          loading: false,
          error: {"error": "Error, Something bad happened."},
        );
      }
    }
  }
}

login_event.dart

abstract class LoginEvent {}

class UserNameInput extends LoginEvent {
  final String username;
  UserNameInput({this.username});
}

class PasswordInput extends LoginEvent {
  final String password;
  PasswordInput({this.password});
}

class Login extends LoginEvent {
  Function callback;
  Login({this.callback});
}

login_state.dart

import 'package:meta/meta.dart';
import '../common_state.dart';

class LoginState extends CommonState {
  final String username;
  final String password;
  bool loading;
  bool loaded;
  Map error;

  LoginState({
    @required this.username,
    @required this.password,
    bool loading,
    bool loaded,
    Map error,
  }) : super(
          loading: loading,
          loaded: loaded,
          error: error,
        );

  factory LoginState.initial() {
    return LoginState(
      username: "",
      password: "",
    );
  }

  LoginState copyWith(
      {bool loading,
      bool loaded,
      Map error,
      String username,
      String uid,
      String password}) {
    return LoginState(
      username: username ?? this.username,
      password: password ?? this.password,
    );
  }
}

Promoter Package

promoter_bloc.dart

import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:block_pattern_event/blocs/viewmodel/promoter_data.dart';
import 'promoter_event.dart';
import 'promoter_state.dart';

class PromoterBloc extends Bloc<PromoterEvent, PromoterState> {

  void callPromoter() {
    dispatch(GetPromoter());
  }

  @override
  PromoterState get initialState => PromoterState.initial();

  @override
  Stream<PromoterState> mapEventToState(PromoterEvent event) async* {
    if (event is GetPromoter) {
      final promoterViewModel = PromoterViewModel();
      yield currentState.copyWith(promoters: promoterViewModel.promoterList());
    }
  }
}

promoter_event.dart

abstract class PromoterEvent {}

class GetPromoter extends PromoterEvent {}

promoter_state.dart

import 'package:block_pattern_event/models/promoter.dart';

class PromoterState {
  final List<PromoterResponse> promoters;

  PromoterState({
    this.promoters,
  });

  factory PromoterState.initial() {
    return PromoterState(
      promoters: List<PromoterResponse>(),
    );
  }

  PromoterState copyWith({
    List<PromoterResponse> promoters
  }) {
    return PromoterState(
      promoters: promoters ?? this.promoters,
    );
  }
}

User Package

user_bloc.dart

import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'user_event.dart';
import 'user_state.dart';

class UserBloc extends Bloc<UserEvent, UserState> {
  SharedPreferences pref;

  void saveUserName(username) {
    dispatch(SaveUserName(username: username));
  }

  void saveId(id) {
    dispatch(SaveId(id: id));
  }

  void saveAuthToken(token) {
    dispatch(SaveToken(token: token));
  }

  void saveEmail(email) {
    dispatch(SaveEmail(email: email));
  }

  void saveMobile(mobile) {
    dispatch(SaveMobile(mobile: mobile));
  }

  void getLoginDetails() {
    dispatch(GetLoginDetails());
  }

  @override
  UserState get initialState => UserState.initial();

  @override
  Stream<UserState> mapEventToState(
    UserEvent event,
  ) async* {
    if (event is SaveUserName) {

      pref.setString("username", event.username);
    }

    if (event is SaveId) {
      pref = await SharedPreferences.getInstance();
      pref.setString("id", event.id);
    }

    if (event is SaveEmail) {
      pref = await SharedPreferences.getInstance();
      pref.setString("email", event.email);
    }

    if (event is SaveToken) {
      pref = await SharedPreferences.getInstance();
      pref.setString("token", event.token);
    }

    if (event is RemoveToken) {
      pref = await SharedPreferences.getInstance();
      pref.remove("token");
    }

    if (event is SaveMobile) {
      pref = await SharedPreferences.getInstance();
      pref.setString("mobile", event.mobile);
    }

    //GET LOGIN DETAILS
    if (event is GetLoginDetails) {
      pref = await SharedPreferences.getInstance();
      yield currentState.copyWith(mobile: pref.getString('mobile'), userName: pref.getString('username'));
    }
  }
}

user_event.dart

abstract class UserEvent {}

class GetLoginDetails extends UserEvent {}

class SaveUserName extends UserEvent {
  final String username;
  SaveUserName({this.username});
}

class SaveId extends UserEvent {
  final String id;
  SaveId({this.id});
}

class SaveToken extends UserEvent {
  final String token;
  SaveToken({this.token});
}

class RemoveToken extends UserEvent {
  final String token;
  RemoveToken({this.token});
}

class SaveEmail extends UserEvent {
  final String email;
  SaveEmail({this.email});
}

class SaveMobile extends UserEvent {
  final String mobile;
  SaveMobile({this.mobile});
}

user_state.dart

import 'package:flutter/material.dart';
import 'package:meta/meta.dart';

class UserState {
  final bool loading, loaded;
  final Map error;
  final String userName, mobile;

  UserState({
    @required this.loading,
    @required this.loaded,
    @required this.error,
    @required this.userName,
    @required this.mobile,
  });

  factory UserState.initial() {
    return UserState(
      loading: false,
      loaded: false,
      error: null,
      userName: null,
      mobile: null,
    );
  }

  UserState copyWith({
    bool loading,
    bool loaded,
    Map error,
    String userName,
    String mobile,
  }) {
    return UserState(
        loading: loading ?? this.loading,
        loaded: loaded ?? this.loaded,
        error: error ?? this.error,
        userName: userName ?? this.userName,
        mobile: mobile ?? this.mobile);
  }
}

– Viewmodel Package

promoter_data.dart

import 'package:block_pattern_event/models/promoter.dart';

class PromoterViewModel {
  List<PromoterResponse> promoterItems;
  PromoterViewModel({this.promoterItems});

  promoterList() => <PromoterResponse>[
        PromoterResponse(promoterId: 1, promoterName: 'Admin'),
        PromoterResponse(promoterId: 1, promoterName: 'User'),
        PromoterResponse(promoterId: 1, promoterName: 'Local'),
        PromoterResponse(promoterId: 1, promoterName: 'Others'),
      ];
}

common_state.dart

abstract class CommonState {
   bool loading = false;
   bool loaded= false;
   Map error;

  CommonState({
    this.loading,
    this.loaded,
    this.error,
  });

  Map<String, dynamic> toMap() => {
    'loading': loading,
    'loaded': loaded,
    'error': error,
  };
}

Models Package

login.dart

class LoginResponse {
  final double id;
  final String firstName, lastName, mobile, username, code;

  LoginResponse({
    this.id,
    this.firstName,
    this.lastName,
    this.username,
    this.code,
    this.mobile,
  });

  LoginResponse copyWith(Map<String, dynamic> json) {
    return LoginResponse(
        id: json["ID"] ?? this.id,
        firstName: json["FNAME"] ?? this.firstName,
        lastName: json["LNAME"] ?? this.lastName,
        username: json["RETAILERNAME"] ?? this.username,
        code: json["RETAILERCODE"] ?? this.code,
        mobile: json["MOBILENO"] ?? this.mobile);
  }

  LoginResponse.fromJson(Map<String, dynamic> json)
      : id = json["ID"],
        firstName = json["FNAME"],
        lastName = json["LNAME"],
        username = json["RETAILERNAME"],
        code = json["RETAILERCODE"],
        mobile = json["MOBILENO"];
}

promoter.dart

class PromoterResponse {
  final double promoterId;
  final String promoterName;

  PromoterResponse({this.promoterId, this.promoterName});
}

– Screens Package

screen package inside 2 package

  • pages : View
  • widgets : Custom widgets

– Pages Package

home_page.dart

import 'package:block_pattern_event/blocs/promoter/promoter_bloc.dart';
import 'package:block_pattern_event/blocs/promoter/promoter_state.dart';
import 'package:block_pattern_event/models/promoter.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

class HomePage extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<HomePage> {
  PromoterBloc promoterBloc;

  @override
  void initState() {
    super.initState();
    promoterBloc = BlocProvider.of<PromoterBloc>(context);

    promoterBloc.callPromoter();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        backgroundColor: Colors.white,
        appBar: AppBar(
          title: Text('Promoter List'),
        ),
        body: Container(
            child: BlocBuilder(
                bloc: promoterBloc,
                builder: (context, PromoterState state) {
                  return ListView.builder(
                      padding: EdgeInsets.only(top: 1.0),
                      physics: BouncingScrollPhysics(),
                      itemCount: state.promoters.length,
                      itemBuilder: (BuildContext context, int index) {
                        PromoterResponse promoter = state.promoters[index];
                        return Material(
                            child: Ink(
                                color: Colors.white,
                                child: ListTile(
                                    title: Text(promoter.promoterName,
                                        style: TextStyle(
                                            color: Colors.black87,
                                            fontSize: 17)),
                                    leading: Container(
                                        width: 40,
                                        height: 40,
                                        child: Align(
                                            alignment: Alignment.center,
                                            child: Text(
                                                promoter.promoterName
                                                    .substring(0, 1),
                                                style: TextStyle(
                                                    color: Colors.black54,
                                                    fontSize: 20))),
                                        decoration: BoxDecoration(
                                            color: Colors.grey.withOpacity(0.1),
                                            borderRadius:
                                                BorderRadius.circular(40.0))),
                                    onTap: () {})));
                      });
                })));
  }
}

login_page.dart

import 'package:block_pattern_event/blocs/login/login_bloc.dart';
import 'package:block_pattern_event/blocs/login/login_state.dart';
import 'package:block_pattern_event/blocs/user/user_bloc.dart';
import 'package:block_pattern_event/models/login.dart';
import 'package:block_pattern_event/screens/widgets/common_dialogs.dart';
import 'package:block_pattern_event/utils/validator.dart';
import 'package:block_pattern_event/utils/vars.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

class LoginPage extends StatefulWidget {
  @override
  _LoginState createState() => _LoginState();
}

class _LoginState extends State<LoginPage> {
  final GlobalKey<FormState> _key = new GlobalKey();
  final TextEditingController _usernameController = new TextEditingController();
  final TextEditingController _passwordController = new TextEditingController();
  final scaffoldKey = new GlobalKey<ScaffoldState>();

  LoginBloc loginBloc;
  UserBloc userBloc;

  bool _validate = false;

  @override
  void initState() {
    super.initState();
    loginBloc = BlocProvider.of<LoginBloc>(context);
    userBloc = BlocProvider.of<UserBloc>(context);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        key: scaffoldKey,
        backgroundColor: Colors.white,
        body: ListView(children: <Widget>[
          Column(children: <Widget>[
            Padding(
              padding: const EdgeInsets.only(top: 57.0, left: 10, right: 10),
              child: Text('Flutter BLoC Pattern Event',
                  style: TextStyle(fontSize: 28), textAlign: TextAlign.center),
            ),
            new Form(key: _key, autovalidate: _validate, child: _bottomSheet()),
          ])
        ]));
  }

  Widget _bottomSheet() {
    return Container(
        margin: EdgeInsets.only(top: MediaQuery.of(context).size.height / 10),
        decoration: BoxDecoration(
          borderRadius: BorderRadius.only(
            topLeft: Radius.circular(24),
            topRight: Radius.circular(24),
          ),
          color: Colors.orange.withOpacity(0.1),
        ),
        alignment: Alignment.bottomCenter,
        padding: EdgeInsets.all(25),
        height: MediaQuery.of(context).size.height / 1.4,
        child: Column(children: <Widget>[
          Text('LOGIN',
              textAlign: TextAlign.center,
              style: TextStyle(
                  fontFamily: ralewayFont,
                  color: Colors.orange.withOpacity(0.8),
                  fontSize: 20,
                  fontWeight: FontWeight.bold)),
          _userNameTextField(),
          _passwordTextField(),
          _signInButton(),
        ]));
  }

  _userNameTextField() => BlocBuilder(
      bloc: loginBloc,
      builder: (BuildContext context, LoginState state) {
        return Padding(
            padding: const EdgeInsets.only(top: 32.0),
            child: TextFormField(
                validator: Validator.validUserName,
                controller: _usernameController,
                keyboardType: TextInputType.text,
                textAlign: TextAlign.left,
                onChanged: loginBloc.userNameInput,
                style: TextStyle(
                    color: Colors.black54,
                    fontFamily: 'quickFont',
                    fontSize: 18,
                    letterSpacing: 0.5),
                decoration: InputDecoration(
                    focusedBorder: UnderlineInputBorder(
                        borderSide: BorderSide(color: Colors.grey)),
                    enabledBorder: UnderlineInputBorder(
                        borderSide: BorderSide(color: Colors.grey)),
                    border: UnderlineInputBorder(
                        borderSide: BorderSide(color: Colors.grey)),
                    focusedErrorBorder: UnderlineInputBorder(
                        borderSide:
                            BorderSide(color: Colors.red.shade200, width: 2)),
                    errorStyle: TextStyle(color: Colors.black54),
                    hintStyle: TextStyle(
                      color: Colors.black54,
                      fontFamily: 'quickFont',
                      fontSize: 15,
                    ),
                    labelStyle: TextStyle(color: Colors.grey, fontSize: 12),
                    labelText: 'Username',
                    hintText: 'Username')));
      });

  _passwordTextField() => BlocBuilder(
      bloc: loginBloc,
      builder: (BuildContext context, LoginState state) {
        return Padding(
            padding: const EdgeInsets.only(top: 15.0),
            child: TextFormField(
                validator: Validator.validatePassword,
                controller: _passwordController,
                keyboardType: TextInputType.emailAddress,
                textAlign: TextAlign.left,
                onChanged: loginBloc.passwordInput,
                style: TextStyle(
                    color: Colors.black54,
                    fontFamily: 'quickFont',
                    fontSize: 18,
                    letterSpacing: 0.5),
                decoration: InputDecoration(
                    focusedBorder: UnderlineInputBorder(
                        borderSide: BorderSide(color: Colors.grey)),
                    enabledBorder: UnderlineInputBorder(
                        borderSide: BorderSide(color: Colors.grey)),
                    border: UnderlineInputBorder(
                        borderSide: BorderSide(color: Colors.grey)),
                    focusedErrorBorder: UnderlineInputBorder(
                        borderSide:
                            BorderSide(color: Colors.red.shade200, width: 2)),
                    errorStyle: TextStyle(color: Colors.black54),
                    hintStyle: TextStyle(
                      color: Colors.black54,
                      fontFamily: 'quickFont',
                      fontSize: 15,
                    ),
                    labelStyle: TextStyle(color: Colors.grey, fontSize: 12),
                    labelText: 'Password',
                    hintText: 'Password')));
      });

  buttonChild() {
    return Text("Login",
        style: TextStyle(
            fontFamily: quickFont,
            color: Colors.white,
            fontSize: 16,
            fontWeight: FontWeight.w500));
  }

  void onRegisterDevice() async {
    showProgress(context);
    loginBloc.login((results) {
      hideProgress(context);
      if (results is LoginResponse) {
        clearData();
        LoginResponse loginResponse = results;

        userBloc.saveAuthToken('');
        userBloc.saveUserName(loginResponse.username);
        userBloc.saveId(loginResponse.code);
        userBloc.saveMobile(loginResponse.mobile);

        Navigator.pushNamed(context, '/homepage');
      } else {}
    });
  }

  _signInButton() => BlocBuilder(
      bloc: loginBloc,
      builder: (BuildContext context, LoginState state) {
        if (state.error != null && state.error.containsKey('error')) {}
        return new Padding(
            padding: const EdgeInsets.only(top: 20.0),
            child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  SizedBox(
                      width: 150,
                      height: 36,
                      child: RaisedButton(
                          color: Colors.orange,
                          onPressed: () {
                            sendToServer();
                          },
                          shape: RoundedRectangleBorder(
                            borderRadius: BorderRadius.circular(8.0),
                          ),
                          elevation: 1,
                          child: buttonChild()))
                ]));
      });

  sendToServer() {
    if (_key.currentState.validate()) {
      _key.currentState.save();
      onRegisterDevice();
    } else {
      setState(() {
        _validate = true;
      });
    }
  }

  clearData() {
    _usernameController.clear();
    _passwordController.clear();
  }
}

– Widgets Package

common_dialogs.dart

import 'package:block_pattern_event/utils/vars.dart';
import 'package:flutter/material.dart';

/*toast(String msg) {
  Fluttertoast.showToast(
      msg: msg,
      toastLength: Toast.LENGTH_SHORT,
      gravity: ToastGravity.BOTTOM,
      backgroundColor: Colors.white,
      textColor: Colors.black);
}*/

showSuccess(BuildContext context, String message, IconData icon) {
  showDialog(
      context: context,
      builder: (context) => Center(
            child: Material(
              borderRadius: BorderRadius.circular(8.0),
              color: Colors.black,
              elevation: 5.0,
              child: Padding(
                padding: const EdgeInsets.all(32.0),
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  mainAxisSize: MainAxisSize.min,
                  children: <Widget>[
                    Icon(
                      icon,
                      color: Colors.green,
                    ),
                    SizedBox(
                      height: 10.0,
                    ),
                    Text(
                      message,
                      style: TextStyle(
                          fontFamily: '$ralewayFont', color: Colors.white),
                    )
                  ],
                ),
              ),
            ),
          ));
}

showProgress(BuildContext context) {
  showDialog(
      context: context,
      barrierDismissible: false,
      builder: (context) => Center(
            child: CircularProgressIndicator()
          ));
}

hideProgress(BuildContext context) {
  Navigator.pop(context);
}

Utils Package

validator.dart

class Validator {
  static String validateMobile(String value) {
    String pattern = r'(^[0-9]*$)';
    RegExp regExp = new RegExp(pattern);
    if (value.replaceAll(" ", "").isEmpty) {
      return 'Mobile is required';
    } else if (value.replaceAll(" ", "").length != 10) {
      return 'Mobile number must 10 digits';
    } else if (!regExp.hasMatch(value.replaceAll(" ", ""))) {
      return 'Mobile number must be digits';
    }
    return null;
  }

  static String validUserName(String value) {
    String pattern = r'(^[a-zA-Z ]*$)';
    RegExp regExp = new RegExp(pattern);
    if (value.isEmpty) {
      return 'Username is required';
    } else if (!regExp.hasMatch(value)) {
      return 'Username must be a-z and A-Z';
    }
    return null;
  }

  static String validateEmail(String value) {
    String pattern =
        r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$';
    RegExp regExp = new RegExp(pattern);
    if (value.isEmpty) {
      return 'Email is required';
    } else if (!regExp.hasMatch(value)) {
      return 'Invalid email';
    } else {
      return null;
    }
  }

  static String validatePassword(String value) {
    if (value.isEmpty) {
      return 'Password is required';
    } else if (value.length < 4) {
      return 'Password must be at least 4 characters';
    }
    return null;
  }

  static String validateConfirmPassword(String value) {
    if (value.isEmpty) {
      return 'Confirm password is required';
    } else if (value.length < 4) {
      return 'Confirm password must be at least 4 characters';
    }
    return null;
  }

  static bool validationEqual(String currentValue, String checkValue) {
    if (currentValue == checkValue) {
      return true;
    } else {
      return false;
    }
  }

  static String address(String value) {
    if (value.isEmpty) {
      return 'Address is required';
    }
    return null;
  }

  static String state(String value) {
    if (value.isEmpty) {
      return 'State is required';
    }
    return null;
  }

  static String flatNoHouseNo(String value) {
    if (value.isEmpty) {
      return 'Flat No. / House No. is required';
    }
    return null;
  }

  static String city(String value) {
    if (value.isEmpty) {
      return 'City is required';
    }
    return null;
  }
}

vars.dart

String appName = "MileStone";
String quickFont = 'Quicksand';
String ralewayFont = 'Raleway';

String quickBoldFont = 'quicksand_bold.otf';
String quickNormalFont = 'quicksand_book.otf';
String quickLightFont = 'quicksand_light.otf';

String homeRoute = '/homepage';

int ok200 = 200;

This file contains

  • Start of application
  • BlocProvider
  • Theme
  • Route

main.dart

import 'package:block_pattern_event/blocs/promoter/promoter_bloc.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'blocs/login/login_bloc.dart';
import 'blocs/user/user_bloc.dart';
import 'screens/pages/login_page.dart';
import 'screens/pages/home_page.dart';
import 'utils/vars.dart';

void main() {
  runApp(StartApp());
}

class StartApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    SystemChrome.setSystemUIOverlayStyle(
      SystemUiOverlayStyle.dark.copyWith(
          statusBarColor: Colors.transparent,
          statusBarIconBrightness: Brightness.light),
    );

    return BlocProvider(
        builder: (context) => UserBloc(),
        child: BlocProvider(
            builder: (context) => LoginBloc(),
            child: BlocProvider(
                builder: (context) => PromoterBloc(),
                child: MaterialApp(
                    theme: ThemeData(
                        //buttonColor: Colors.white,
                        brightness: Brightness.light,
                        accentColor: Colors.orange,
                        primaryColor: Colors.orangeAccent,
                        primarySwatch: Colors.orange,
                        fontFamily: quickFont),
                    initialRoute: '/',
                    debugShowCheckedModeBanner: false,
                    routes: <String, WidgetBuilder>{
                      '/': (context) => LoginPage(),
                      '/homepage': (context) => HomePage()//LoginPage
                    }))));
  }
}

The flutter tutorial  is a website that bring you the latest and amazing resources of code. All the languages codes are included in this website. The languages like flutter, android, java,kotlin etc.with the help of this languages any user can develop the beautiful application

For more information about Flutter. visit www.fluttertutorial.in