flutter_bloc 0.3.1

  • README.md
  • CHANGELOG.md
  • Example
  • Installing
  • Versions
  • new93
Flutter Bloc Package

Build Status codecov Pub License: MIT Gitter


A Flutter package that helps implement the Bloc pattern.

This package is built to work with bloc ^0.6.0.

Bloc Widgets

BlocBuilder is a Flutter widget which requires a Bloc and a builder function. BlocBuilder handles building the widget in response to new states. BlocBuilder is very similar to StreamBuilder but has a more simple API to reduce the amount of boilerplate code needed.

BlocProvider is a Flutter widget which provides a bloc to its children via BlocProvider.of(context). It is used as a DI widget so that a single instance of a bloc can be provided to multiple widgets within a subtree.

Usage

Lets take a look at how to use BlocBuilder to hook up a LoginForm widget to a LoginBloc.

  class LoginForm extends StatelessWidget {
    final LoginBloc loginBloc;
    final usernameController = TextEditingController();
    final passwordController = TextEditingController();

    const LoginForm({Key key, @required this.loginBloc}): super(key: key);

    @override
    Widget build(BuildContext context) {
      return BlocBuilder<LoginEvent, LoginState>(
        bloc: loginBloc,
        builder: (
          BuildContext context,
          LoginState loginState,
        ) {
          if (loginState.token.isNotEmpty) {
            // user is authenticated do something...
          }

          return Form(
            child: Column(
              children: [
                Text(
                  loginState.error,
                ),
                TextFormField(
                  decoration: InputDecoration(labelText: 'username'),
                  controller: usernameController,
                ),
                TextFormField(
                  decoration: InputDecoration(labelText: 'password'),
                  controller: passwordController,
                  obscureText: true,
                ),
                RaisedButton(
                  onPressed: loginState.isLoginButtonEnabled
                      ? _onLoginButtonPressed
                      : null,
                  child: Text('Login'),
                ),
                Container(
                  child:
                      loginState.isLoading ? CircularProgressIndicator() : null,
                ),
              ],
            ),
          );
        },
      );
    }

    _onLoginButtonPressed() {
      loginBloc.onLoginButtonPressed(
        username: usernameController.text,
        password: passwordController.text,
      );
    }
  }

At this point we have sucessfully separated our presentational layer from our business logic layer. Notice that the LoginForm widget knows nothing about what happens when a user taps the button. The form simply tells the LoginBloc that the user has pressed the button.

Dart Versions

  • Dart 2: >= 2.0.0

Examples

  • Simple Counter Example - an example of how to create a CounterBloc to implement the classic Flutter Counter app.
  • Login Flow Example - an example of how to use the bloc and flutter_bloc packages to implement a Login Flow.

Contributors

0.1.0

Initial Version of the library.

  • Includes the ability to connect presentation layer to Bloc by using the BlocBuilder Widget.
  • Includes BlocProvider, a DI widget that allows a single instance of a bloc to be provided to multiple widgets within a subtree.

0.1.1

Minor Updates to Documentation

0.2.0

Updates to BlocBuilder and BlocProvider

  • BlocBuilder does not automatically dispose a Bloc. Developers are now responsible for determining when to call Bloc.dispose()
  • BlocProvider support for of(context) with generics
    • Support for multiple nested BlocProviders with different Bloc Types.

0.2.1

Minor Updates to Documentation

0.3.0

Updated to bloc: ^0.6.0

0.3.1

Minor Updates to Documentation

example/lib/main.dart

import 'dart:async';

import 'package:flutter/material.dart';

import 'package:bloc/bloc.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => MyAppState();
}

class MyAppState extends State<MyApp> {
  final CounterBloc _counterBloc = CounterBloc();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: BlocProvider<CounterBloc>(
        bloc: _counterBloc,
        child: CounterPage(),
      ),
    );
  }
}

class CounterPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final CounterBloc _counterBloc = BlocProvider.of<CounterBloc>(context);

    return Scaffold(
      appBar: AppBar(title: Text('Counter')),
      body: BlocBuilder<CounterEvent, int>(
        bloc: _counterBloc,
        builder: (BuildContext context, int count) {
          return Center(
            child: Text(
              '$count',
              style: TextStyle(fontSize: 24.0),
            ),
          );
        },
      ),
      floatingActionButton: Column(
        crossAxisAlignment: CrossAxisAlignment.end,
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget>[
          Padding(
            padding: EdgeInsets.symmetric(vertical: 5.0),
            child: FloatingActionButton(
              child: Icon(Icons.add),
              onPressed: _counterBloc.increment,
            ),
          ),
          Padding(
            padding: EdgeInsets.symmetric(vertical: 5.0),
            child: FloatingActionButton(
              child: Icon(Icons.remove),
              onPressed: _counterBloc.decrement,
            ),
          ),
        ],
      ),
    );
  }
}

abstract class CounterEvent {}

class IncrementCounter extends CounterEvent {
  @override
  String toString() => 'IncrementCounter';
}

class DecrementCounter extends CounterEvent {
  @override
  String toString() => 'DecrementCounter';
}

class CounterBloc extends Bloc<CounterEvent, int> {
  void increment() {
    dispatch(IncrementCounter());
  }

  void decrement() {
    dispatch(DecrementCounter());
  }

  @override
  int get initialState => 0;

  @override
  void onTransition(Transition<CounterEvent, int> transition) {
    print(transition.toString());
  }

  @override
  Stream<int> mapEventToState(int state, CounterEvent event) async* {
    if (event is IncrementCounter) {
      yield state + 1;
    }
    if (event is DecrementCounter) {
      yield state - 1;
    }
  }
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  flutter_bloc: ^0.3.1

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter packages get

Alternatively, your editor might support flutter packages get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:flutter_bloc/flutter_bloc.dart';
  
Version Uploaded Documentation Archive
0.3.1 Nov 16, 2018 Go to the documentation of flutter_bloc 0.3.1 Download flutter_bloc 0.3.1 archive
0.3.0 Oct 26, 2018 Go to the documentation of flutter_bloc 0.3.0 Download flutter_bloc 0.3.0 archive
0.2.1 Oct 24, 2018 Go to the documentation of flutter_bloc 0.2.1 Download flutter_bloc 0.2.1 archive
0.2.0 Oct 23, 2018 Go to the documentation of flutter_bloc 0.2.0 Download flutter_bloc 0.2.0 archive
0.1.1 Oct 23, 2018 Go to the documentation of flutter_bloc 0.1.1 Download flutter_bloc 0.1.1 archive
0.1.0 Oct 23, 2018 Go to the documentation of flutter_bloc 0.1.0 Download flutter_bloc 0.1.0 archive
Popularity:
Describes how popular the package is relative to other packages. [more]
86
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
93
Learn more about scoring.

We analyzed this package on Nov 16, 2018, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.0.0
  • pana: 0.12.6
  • Flutter: 0.11.3

Platforms

Detected platforms: Flutter

References Flutter, and has no conflicting libraries.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.0.0-dev.28.0 <3.0.0
bloc ^0.6.0 0.6.0
flutter 0.0.0
rxdart >=0.18.1 <1.0.0 0.19.0
Transitive dependencies
collection 1.14.11
meta 1.1.6
sky_engine 0.0.99
typed_data 1.1.6
vector_math 2.0.8
Dev dependencies
flutter_test
test >=1.3.0 <2.0.0