flutter_bloc State management Dart Package

Bloc

build codecov Star on Github Flutter Website Awesome Flutter Flutter Samples License: MIT Discord Bloc Library


A predictable state management library that helps implement the BLoC design pattern.

PackagePubblocpub packagebloc_testpub packagebloc_concurrencypub packageflutter_blocpub packageangular_blocpub packagehydrated_blocpub packagereplay_blocpub packagesealed_flutter_blocpub package



Sponsors

Our top sponsors are shown below! [Become a Sponsor]

Try the Flutter Chat Tutorial ðŸ’¬



Overview

Bloc Architecture

The goal of this library is to make it easy to separate presentation from business logic, facilitating testability and reusability.


Documentation


Migration


Examples


Dart

  • Counter - an example of how to create a CounterBloc (pure dart).


Flutter

  • Counter - an example of how to create a CounterBloc to implement the classic Flutter Counter app.
  • Form Validation - an example of how to use the bloc and flutter_bloc packages to implement form validation.
  • Bloc with Stream - an example of how to hook up a bloc to a Stream and update the UI in response to data from the Stream.
  • Complex List - an example of how to manage a list of items and asynchronously delete items one at a time using bloc and flutter_bloc.
  • 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.
  • Firebase Login - an example of how to use the bloc and flutter_bloc packages to implement login via Firebase.
  • 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.
  • Timer - an example of how to create a Timer using the bloc and flutter_bloc packages.
  • Shopping Cart - an example of how to create a Shopping Cart Application using the bloc and flutter_bloc packages based on flutter samples.
  • Dynamic Form - an example of how to use the bloc and flutter_bloc packages to implement a dynamic form which pulls data from a repository.
  • Wizard - an example of how to build a multi-step wizard using the bloc and flutter_bloc packages.
  • Fluttersaurus - an example of how to use the bloc and flutter_bloc packages to create a thesaurus app -- made for Bytconf Flutter 2020.
  • I/O Photo Booth - an example of how to use the bloc and flutter_bloc packages to create a virtual photo booth web app -- made for Google I/O 2021.
  • I/O Pinball - an example of how to use the bloc and flutter_bloc packages to create a pinball web app -- made for Google I/O 2022.


Web

  • Counter - an example of how to use a CounterBloc in an AngularDart app.
  • Github Search - an example of how to create a Github Search Application using the bloc and angular_bloc packages.


Flutter + Web

  • Github Search - an example of how to create a Github Search Application and share code between Flutter and AngularDart.


Articles


Books

  • Flutter Complete Reference - A book about the Dart programming language (version 2.10, with null safety support) and the Flutter framework (version 1.20). It covers the bloc package (version 6.0.3) in all flavors: bloc, flutter_bloc hydrated_bloc, replay_bloc, bloc_test and cubit.


Extensions

  • IntelliJ - extends IntelliJ/Android Studio with support for the Bloc library and provides tools for effectively creating Blocs for both Flutter and AngularDart apps.
  • VSCode - extends VSCode with support for the Bloc library and provides tools for effectively creating Blocs for both Flutter and AngularDart apps.


Community

Learn more at the following links, which have been contributed by the community.


Packages


Video Tutorials


Written Resources


Extensions


Maintainers

Example

example/lib/main.dart

// ignore_for_file: avoid_print

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

void main() {
  Bloc.observer = const AppBlocObserver();
  runApp(const App());
}

/// {@template app_bloc_observer}
/// Custom [BlocObserver] that observes all bloc and cubit state changes.
/// {@endtemplate}
class AppBlocObserver extends BlocObserver {
  /// {@macro app_bloc_observer}
  const AppBlocObserver();

  @override
  void onChange(BlocBase<dynamic> bloc, Change<dynamic> change) {
    super.onChange(bloc, change);
    if (bloc is Cubit) print(change);
  }

  @override
  void onTransition(
    Bloc<dynamic, dynamic> bloc,
    Transition<dynamic, dynamic> transition,
  ) {
    super.onTransition(bloc, transition);
    print(transition);
  }
}

/// {@template app}
/// A [StatelessWidget] that:
/// * uses [bloc](https://pub.dev/packages/bloc) and
/// [flutter_bloc](https://pub.dev/packages/flutter_bloc)
/// to manage the state of a counter and the app theme.
/// {@endtemplate}
class App extends StatelessWidget {
  /// {@macro app}
  const App({super.key});

  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (_) => ThemeCubit(),
      child: const AppView(),
    );
  }
}

/// {@template app_view}
/// A [StatelessWidget] that:
/// * reacts to state changes in the [ThemeCubit]
/// and updates the theme of the [MaterialApp].
/// * renders the [CounterPage].
/// {@endtemplate}
class AppView extends StatelessWidget {
  /// {@macro app_view}
  const AppView({super.key});

  @override
  Widget build(BuildContext context) {
    return BlocBuilder<ThemeCubit, ThemeData>(
      builder: (_, theme) {
        return MaterialApp(
          theme: theme,
          home: const CounterPage(),
        );
      },
    );
  }
}

/// {@template counter_page}
/// A [StatelessWidget] that:
/// * provides a [CounterBloc] to the [CounterView].
/// {@endtemplate}
class CounterPage extends StatelessWidget {
  /// {@macro counter_page}
  const CounterPage({super.key});

  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (_) => CounterBloc(),
      child: const CounterView(),
    );
  }
}

/// {@template counter_view}
/// A [StatelessWidget] that:
/// * demonstrates how to consume and interact with a [CounterBloc].
/// {@endtemplate}
class CounterView extends StatelessWidget {
  /// {@macro counter_view}
  const CounterView({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Counter')),
      body: Center(
        child: BlocBuilder<CounterBloc, int>(
          builder: (context, count) {
            return Text(
              '$count',
              style: Theme.of(context).textTheme.displayLarge,
            );
          },
        ),
      ),
      floatingActionButton: Column(
        crossAxisAlignment: CrossAxisAlignment.end,
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget>[
          FloatingActionButton(
            child: const Icon(Icons.add),
            onPressed: () {
              context.read<CounterBloc>().add(CounterIncrementPressed());
            },
          ),
          const SizedBox(height: 4),
          FloatingActionButton(
            child: const Icon(Icons.remove),
            onPressed: () {
              context.read<CounterBloc>().add(CounterDecrementPressed());
            },
          ),
          const SizedBox(height: 4),
          FloatingActionButton(
            child: const Icon(Icons.brightness_6),
            onPressed: () {
              context.read<ThemeCubit>().toggleTheme();
            },
          ),
        ],
      ),
    );
  }
}

/// Event being processed by [CounterBloc].
abstract class CounterEvent {}

/// Notifies bloc to increment state.
class CounterIncrementPressed extends CounterEvent {}

/// Notifies bloc to decrement state.
class CounterDecrementPressed extends CounterEvent {}

/// {@template counter_bloc}
/// A simple [Bloc] that manages an `int` as its state.
/// {@endtemplate}
class CounterBloc extends Bloc<CounterEvent, int> {
  /// {@macro counter_bloc}
  CounterBloc() : super(0) {
    on<CounterIncrementPressed>((event, emit) => emit(state + 1));
    on<CounterDecrementPressed>((event, emit) => emit(state - 1));
  }
}

/// {@template brightness_cubit}
/// A simple [Cubit] that manages the [ThemeData] as its state.
/// {@endtemplate}
class ThemeCubit extends Cubit<ThemeData> {
  /// {@macro brightness_cubit}
  ThemeCubit() : super(_lightTheme);

  static final _lightTheme = ThemeData(
    floatingActionButtonTheme: const FloatingActionButtonThemeData(
      foregroundColor: Colors.white,
    ),
    brightness: Brightness.light,
  );

  static final _darkTheme = ThemeData(
    floatingActionButtonTheme: const FloatingActionButtonThemeData(
      foregroundColor: Colors.black,
    ),
    brightness: Brightness.dark,
  );

  /// Toggles the current brightness between light and dark.
  void toggleTheme() {
    emit(state.brightness == Brightness.dark ? _lightTheme : _darkTheme);
  }
}

GitHub

View GitHub



Description of the image

Related Posts