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

Libraries

flutter_bloc