flutter_bloc 0.9.0

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

Pub Build Status codecov Flutter.io Awesome Flutter Flutter Samples Star on GitHub Gitter License: MIT


A Flutter package that helps implement the BLoC pattern.

This package is built to work with bloc.

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.

BlocBuilder(
  bloc: BlocA(),
  builder: (context, state) {
    // return widget here based on BlocA's state
  }
)

BlocProvider is a Flutter widget which provides a bloc to its children via BlocProvider.of<T>(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.

BlocProvider(
  bloc: BlocA(),
  child: ChildA(),
);

then from ChildA we can retrieve BlocA with:

BlocProvider.of<BlocA>(context)

BlocProviderTree is a Flutter widget that merges multiple BlocProvider widgets into one. BlocProviderTree improves the readability and eliminates the need to nest multiple BlocProviders. By using BlocProviderTree we can go from:

BlocProvider<BlocA>(
   bloc: BlocA(),
   child: BlocProvider<BlocB>(
     bloc: BlocB(),
     child: BlocProvider<BlocC>(
       value: BlocC(),
       child: ChildA(),
     )
   )
 )

to:

BlocProviderTree(
  blocProviders: [
    BlocProvider<BlocA>(bloc: BlocA()),
    BlocProvider<BlocB>(bloc: BlocB()),
    BlocProvider<BlocC>(bloc: BlocC()),
  ],
  child: ChildA(),
)

Usage #

Lets take a look at how to use BlocBuilder to hook up a CounterPage widget to a CounterBloc.

counter_bloc.dart

enum CounterEvent { increment, decrement }

class CounterBloc extends Bloc<CounterEvent, int> {
  @override
  int get initialState => 0;

  @override
  Stream<int> mapEventToState(CounterEvent event) async* {
    switch (event) {
      case CounterEvent.decrement:
        yield currentState - 1;
        break;
      case CounterEvent.increment:
        yield currentState + 1;
        break;
    }
  }
}

counter_page.dart

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.dispatch(CounterEvent.increment);
              },
            ),
          ),
          Padding(
            padding: EdgeInsets.symmetric(vertical: 5.0),
            child: FloatingActionButton(
              child: Icon(Icons.remove),
              onPressed: () {
                _counterBloc.dispatch(CounterEvent.decrement);
              },
            ),
          ),
        ],
      ),
    );
  }
}

At this point we have successfully separated our presentational layer from our business logic layer. Notice that the CounterPage widget knows nothing about what happens when a user taps the buttons. The widget simply tells the CounterBloc that the user has pressed either the increment or decrement button.

Dart Versions #

  • Dart 2: >= 2.0.0

Examples #

  • Counter - an example of how to create a CounterBloc to implement the classic Flutter Counter app.
  • Infinite List - an example of how to use the bloc and flutter_bloc packages to implement an infinite scrolling list.
  • Login Flow - an example of how to use the bloc and flutter_bloc packages to implement a Login Flow.
  • Github Search - an example of how to create a Github Search Application using the bloc and flutter_bloc packages.
  • Weather - an example of how to create a Weather Application using the bloc and flutter_bloc packages. The app uses a RefreshIndicator to implement "pull-to-refresh" as well as dynamic theming.
  • Todos - an example of how to create a Todos Application using the bloc and flutter_bloc packages.

Maintainers #

0.9.0 #

Updated to bloc: ^0.11.0 and Documentation Updates

0.8.0 #

Updated to bloc: ^0.10.0 and Documentation Updates

0.7.1 #

Minor Updates to Documentation.

0.7.0 #

Added BlocProviderTree and Documentation Updates

0.6.3 #

Updated to bloc:^0.9.3 and Minor Updates to Documentation

0.6.2 #

Additional Minor Updates to Documentation

0.6.1 #

Minor Updates to Documentation

0.6.0 #

Updated to bloc: ^0.9.0

0.5.4 #

Additional Minor Updates to Documentation

0.5.3 #

Additional Minor Updates to Documentation

0.5.2 #

Minor Updates to Documentation

0.5.1 #

BlocProvider performance improvements

0.5.0 #

Updated to bloc: ^0.8.0

0.4.12 #

Additional Minor Updates to Documentation

0.4.11 #

Additional Minor Updates to Documentation

0.4.10 #

Additional BlocBuilder enhancements

  • BlocBuilder no longer filters out States giving developers full control

Minor Updates to Documentation and Examples

0.4.9 #

Additional BlocBuilder enhancements

  • BlocBuilder no longer has a dependency on RxDart
  • Using bloc: ">=0.7.5 <0.8.0"

0.4.8 #

Additional BlocProvider performance improvements

0.4.7 #

Minor Updates to Documentation and Examples

0.4.6 #

Bug Fixes

  • Fixed bug where BlocBuilder would return initial state instead of the latest state

0.4.5 #

Additional Minor Updates to Documentation

0.4.4 #

Minor updates to documentation and improved error reporting in BlocProvider

0.4.3 #

BlocBuilder performance improvements

0.4.2 #

BlocProvider performance improvements

0.4.1 #

Minor Updates to Documentation

0.4.0 #

Updated to bloc: ^0.7.0

0.3.1 #

Minor Updates to Documentation

0.3.0 #

Updated to bloc: ^0.6.0

0.2.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.1.1 #

Minor Updates to Documentation

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.

example/lib/main.dart

import 'dart:async';

import 'package:flutter/material.dart';

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

class SimpleBlocDelegate extends BlocDelegate {
  @override
  void onTransition(Transition transition) {
    print(transition);
  }

  @override
  void onError(Object error, StackTrace stacktrace) {
    print(error);
  }
}

void main() {
  BlocSupervisor().delegate = SimpleBlocDelegate();
  runApp(App());
}

class App extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _AppState();
}

class _AppState extends State<App> {
  final CounterBloc _counterBloc = CounterBloc();
  final ThemeBloc _themeBloc = ThemeBloc();

  @override
  Widget build(BuildContext context) {
    return BlocProviderTree(
      blocProviders: [
        BlocProvider<CounterBloc>(bloc: _counterBloc),
        BlocProvider<ThemeBloc>(bloc: _themeBloc)
      ],
      child: BlocBuilder(
        bloc: _themeBloc,
        builder: (_, ThemeData theme) {
          return MaterialApp(
            title: 'Flutter Demo',
            home: CounterPage(),
            theme: theme,
          );
        },
      ),
    );
  }

  @override
  void dispose() {
    _counterBloc.dispose();
    _themeBloc.dispose();
    super.dispose();
  }
}

class CounterPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final CounterBloc _counterBloc = BlocProvider.of<CounterBloc>(context);
    final ThemeBloc _themeBloc = BlocProvider.of<ThemeBloc>(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.dispatch(CounterEvent.increment);
              },
            ),
          ),
          Padding(
            padding: EdgeInsets.symmetric(vertical: 5.0),
            child: FloatingActionButton(
              child: Icon(Icons.remove),
              onPressed: () {
                _counterBloc.dispatch(CounterEvent.decrement);
              },
            ),
          ),
          Padding(
            padding: EdgeInsets.symmetric(vertical: 5.0),
            child: FloatingActionButton(
              child: Icon(Icons.update),
              onPressed: () {
                _themeBloc.dispatch(ThemeEvent.toggle);
              },
            ),
          ),
        ],
      ),
    );
  }
}

enum CounterEvent { increment, decrement }

class CounterBloc extends Bloc<CounterEvent, int> {
  @override
  int get initialState => 0;

  @override
  Stream<int> mapEventToState(CounterEvent event) async* {
    switch (event) {
      case CounterEvent.decrement:
        yield currentState - 1;
        break;
      case CounterEvent.increment:
        yield currentState + 1;
        break;
    }
  }
}

enum ThemeEvent { toggle }

class ThemeBloc extends Bloc<ThemeEvent, ThemeData> {
  @override
  ThemeData get initialState => ThemeData.light();

  @override
  Stream<ThemeData> mapEventToState(ThemeEvent event) async* {
    switch (event) {
      case ThemeEvent.toggle:
        yield currentState == ThemeData.dark()
            ? ThemeData.light()
            : ThemeData.dark();
        break;
    }
  }
}

Use this package as a library

1. Depend on it

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


dependencies:
  flutter_bloc: ^0.9.0

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.9.0 Mar 24, 2019 Go to the documentation of flutter_bloc 0.9.0 Download flutter_bloc 0.9.0 archive
0.8.0 Mar 19, 2019 Go to the documentation of flutter_bloc 0.8.0 Download flutter_bloc 0.8.0 archive
0.7.1 Mar 8, 2019 Go to the documentation of flutter_bloc 0.7.1 Download flutter_bloc 0.7.1 archive
0.7.0 Feb 24, 2019 Go to the documentation of flutter_bloc 0.7.0 Download flutter_bloc 0.7.0 archive
0.6.3 Feb 21, 2019 Go to the documentation of flutter_bloc 0.6.3 Download flutter_bloc 0.6.3 archive
0.6.2 Feb 16, 2019 Go to the documentation of flutter_bloc 0.6.2 Download flutter_bloc 0.6.2 archive
0.6.1 Feb 16, 2019 Go to the documentation of flutter_bloc 0.6.1 Download flutter_bloc 0.6.1 archive
0.6.0 Feb 13, 2019 Go to the documentation of flutter_bloc 0.6.0 Download flutter_bloc 0.6.0 archive
0.5.4 Feb 5, 2019 Go to the documentation of flutter_bloc 0.5.4 Download flutter_bloc 0.5.4 archive
0.5.3 Jan 27, 2019 Go to the documentation of flutter_bloc 0.5.3 Download flutter_bloc 0.5.3 archive

All 32 versions...

Popularity:
Describes how popular the package is relative to other packages. [more]
99
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]
99
Learn more about scoring.

We analyzed this package on Mar 24, 2019, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.2.0
  • pana: 0.12.14
  • Flutter: 1.3.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.11.0 0.11.0
flutter 0.0.0
Transitive dependencies
collection 1.14.11
meta 1.1.6 1.1.7
rxdart 0.21.0
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