CINXE.COM
flutter_bloc | Flutter package
<!DOCTYPE html> <html lang="en-us"><head><script src="https://www.googletagmanager.com/gtm.js?id=GTM-MX6DBN9" async="async"></script><script src="/static/hash-o6oemknr/js/gtm.js" async="async"></script><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="ie=edge"/><meta name="viewport" content="width=device-width, initial-scale=1"/><meta name="twitter:card" content="summary"/><meta name="twitter:site" content="@dart_lang"/><meta name="twitter:description" content="Flutter Widgets that make it easy to implement the BLoC (Business Logic Component) design pattern. Built to be used with the bloc state management package."/><meta name="twitter:image" content="https://pub.dev/static/hash-o6oemknr/img/pub-dev-icon-cover-image.png"/><meta property="og:type" content="website"/><meta property="og:site_name" content="Dart packages"/><meta property="og:title" content="flutter_bloc | Flutter package"/><meta property="og:description" content="Flutter Widgets that make it easy to implement the BLoC (Business Logic Component) design pattern. Built to be used with the bloc state management package."/><meta property="og:image" content="https://pub.dev/static/hash-o6oemknr/img/pub-dev-icon-cover-image.png"/><meta property="og:url" content="https://pub.dev/packages/flutter_bloc"/><title>flutter_bloc | Flutter package</title><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Google+Sans:wght@400;500;700&family=Google+Sans+Display:wght@400&family=Google+Sans+Text:wght@400;500;700&family=Google+Sans+Mono:wght@400;700&display=swap"/><link rel="shortcut icon" href="/static/hash-o6oemknr/img/flutter-logo-32x32.png"/><link rel="stylesheet" href="https://www.gstatic.com/glue/v25_0/ccb.min.css"/><link rel="search" type="application/opensearchdescription+xml" title="Dart packages" href="/osd.xml"/><link rel="canonical" href="https://pub.dev/packages/flutter_bloc"/><meta name="description" content="Flutter Widgets that make it easy to implement the BLoC (Business Logic Component) design pattern. Built to be used with the bloc state management package."/><link rel="alternate" type="application/atom+xml" title="Updated Packages Feed for Pub" href="/feed.atom"/><link rel="stylesheet" type="text/css" href="/static/hash-o6oemknr/material/bundle/styles.css"/><link rel="stylesheet" type="text/css" href="/static/hash-o6oemknr/css/style.css"/><script src="/static/hash-o6oemknr/material/bundle/script.min.js" defer="defer"></script><script src="/static/hash-o6oemknr/js/script.dart.js" defer="defer"></script><script src="https://www.gstatic.com/brandstudio/kato/cookie_choice_component/cookie_consent_bar.v3.js" defer="defer" data-autoload-cookie-consent-bar="true"></script><meta name="pub-page-data" content="eyJwa2dEYXRhIjp7InBhY2thZ2UiOiJmbHV0dGVyX2Jsb2MiLCJ2ZXJzaW9uIjoiOC4xLjYiLCJsaWtlcyI6NzMxNSwicHVibGlzaGVySWQiOiJibG9jbGlicmFyeS5kZXYiLCJpc0Rpc2NvbnRpbnVlZCI6ZmFsc2UsImlzTGF0ZXN0Ijp0cnVlfSwic2Vzc2lvbkF3YXJlIjpmYWxzZX0="/><link rel="preload" href="/static/hash-o6oemknr/highlight/highlight-with-init.js" as="script"/></head><body class="light-theme"><script src="/static/hash-o6oemknr/js/dark-init.js"></script><noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-MX6DBN9" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript><div class="site-header"><button class="hamburger" aria-label="menu toggle"></button><a class="logo" href="/"><img class="site-logo" src="/static/hash-o6oemknr/img/pub-dev-logo.svg" alt="" width="140" height="30" role="presentation"/></a><div class="site-header-space"></div><div class="site-header-mask"></div><div class="site-header-search"><form action="/packages" method="GET"><input class="site-header-search-input" name="q" placeholder="New search..." autocomplete="on" title="Search"/></form></div><nav class="site-header-nav scroll-container"><div class="nav-login-container"><button id="-account-login" class="nav-main-button link">Sign in</button></div><div class="nav-container nav-help-container hoverable"><button class="nav-main-button">Help</button><div class="nav-hover-popup"><div class="nav-table-columns"><div class="nav-table-column"><h3>Pub.dev</h3><a class="nav-link" href="/help/search" rel="noopener" target="_blank">Searching for packages</a><a class="nav-link" href="/help/scoring" rel="noopener" target="_blank">Package scoring and pub points</a></div><div class="nav-table-column"><h3>Flutter</h3><a class="nav-link" href="https://flutter.dev/using-packages/" rel="noopener" target="_blank">Using packages</a><a class="nav-link" href="https://flutter.dev/developing-packages/" rel="noopener" target="_blank">Developing packages and plugins</a><a class="nav-link" href="https://dart.dev/tools/pub/publishing" rel="noopener" target="_blank">Publishing a package</a></div><div class="nav-table-column"><h3>Dart</h3><a class="nav-link" href="https://dart.dev/guides/packages" rel="noopener" target="_blank">Using packages</a><a class="nav-link" href="https://dart.dev/tools/pub/publishing" rel="noopener" target="_blank">Publishing a package</a></div></div></div></div><div class="nav-container nav-help-container-mobile foldable"><h3 class="foldable-button">Pub.dev <img class="foldable-icon" src="/static/hash-o6oemknr/img/nav-mobile-foldable-icon.svg" alt="toggle folding of the section" width="13" height="6"/></h3><div class="foldable-content"><a class="nav-link" href="/help/search" rel="noopener" target="_blank">Searching for packages</a><a class="nav-link" href="/help/scoring" rel="noopener" target="_blank">Package scoring and pub points</a></div></div><div class="nav-container nav-help-container-mobile foldable"><h3 class="foldable-button">Flutter <img class="foldable-icon" src="/static/hash-o6oemknr/img/nav-mobile-foldable-icon.svg" alt="toggle folding of the section" width="13" height="6"/></h3><div class="foldable-content"><a class="nav-link" href="https://flutter.dev/using-packages/" rel="noopener" target="_blank">Using packages</a><a class="nav-link" href="https://flutter.dev/developing-packages/" rel="noopener" target="_blank">Developing packages and plugins</a><a class="nav-link" href="https://dart.dev/tools/pub/publishing" rel="noopener" target="_blank">Publishing a package</a></div></div><div class="nav-container nav-help-container-mobile foldable"><h3 class="foldable-button">Dart <img class="foldable-icon" src="/static/hash-o6oemknr/img/nav-mobile-foldable-icon.svg" alt="toggle folding of the section" width="13" height="6"/></h3><div class="foldable-content"><a class="nav-link" href="https://dart.dev/guides/packages" rel="noopener" target="_blank">Using packages</a><a class="nav-link" href="https://dart.dev/tools/pub/publishing" rel="noopener" target="_blank">Publishing a package</a></div></div></nav></div><div id="banner-container"></div><main class="container"><div class="detail-wrapper -active -has-info-box"><div class="detail-banners"><a href="https://flutter.dev/docs/development/packages-and-plugins/favorites" rel="noopener" target="_blank"><img class="ff-banner ff-banner-desktop displayed-in-light-theme" src="/static/hash-o6oemknr/img/ff-banner-desktop-2x.png" alt="" width="150" height="218" title="Package is a Flutter Favorite" role="presentation"/><img class="ff-banner ff-banner-desktop displayed-in-dark-theme" src="/static/hash-o6oemknr/img/ff-banner-desktop-dark-2x.png" alt="" width="150" height="218" title="Package is a Flutter Favorite" role="presentation"/><img class="ff-banner ff-banner-mobile displayed-in-light-theme" src="/static/hash-o6oemknr/img/ff-banner-mobile-2x.png" alt="" width="94" height="116" title="Package is a Flutter Favorite" role="presentation"/><img class="ff-banner ff-banner-mobile displayed-in-dark-theme" src="/static/hash-o6oemknr/img/ff-banner-mobile-dark-2x.png" alt="" width="94" height="116" title="Package is a Flutter Favorite" role="presentation"/></a></div><div class="detail-header -is-loose"><div class="detail-container"><div class="detail-header-outer-block"><div class="detail-header-content-block"><h1 class="title">flutter_bloc 8.1.6 <span class="pkg-page-title-copy"><img class="pkg-page-title-copy-icon filter-invert-on-dark" src="/static/hash-o6oemknr/img/content-copy-icon.svg" alt="copy "flutter_bloc: ^8.1.6" to clipboard" width="18" height="18" title="Copy "flutter_bloc: ^8.1.6" to clipboard" data-copy-content="flutter_bloc: ^8.1.6" data-ga-click-event="copy-package-version"/><div class="pkg-page-title-copy-feedback"><span class="code">flutter_bloc: ^8.1.6</span> copied to clipboard</div></span></h1><div class="metadata">Published <span><a class="-x-ago" href="" title="Jun 11, 2024" aria-label="5 months ago" aria-role="button" role="button" data-timestamp="1718080834623">5 months ago</a></span> • <a class="-pub-publisher" href="/publishers/bloclibrary.dev"><img class="-pub-publisher-shield filter-invert-on-dark" src="/static/hash-o6oemknr/img/material-icon-verified.svg" alt="verified publisher" width="14" height="14" title="Published by a pub.dev verified publisher"/>bloclibrary.dev</a><span class="package-badge" title="Package is compatible with Dart 3.">Dart 3 compatible</span></div><div class="detail-tags-and-like"><div class="detail-tags"><div class="-pub-tag-badge"><span class="tag-badge-main">SDK</span><a class="tag-badge-sub" href="/packages?q=sdk%3Aflutter" rel="nofollow" title="Packages compatible with Flutter SDK">Flutter</a></div><div class="-pub-tag-badge"><span class="tag-badge-main">Platform</span><a class="tag-badge-sub" href="/packages?q=platform%3Aandroid" rel="nofollow" title="Packages compatible with Android platform">Android</a><a class="tag-badge-sub" href="/packages?q=platform%3Aios" rel="nofollow" title="Packages compatible with iOS platform">iOS</a><a class="tag-badge-sub" href="/packages?q=platform%3Alinux" rel="nofollow" title="Packages compatible with Linux platform">Linux</a><a class="tag-badge-sub" href="/packages?q=platform%3Amacos" rel="nofollow" title="Packages compatible with macOS platform">macOS</a><a class="tag-badge-sub" href="/packages?q=platform%3Aweb" rel="nofollow" title="Packages compatible with Web platform">web</a><a class="tag-badge-sub" href="/packages?q=platform%3Awindows" rel="nofollow" title="Packages compatible with Windows platform">Windows</a></div></div><div class="detail-like"><button id="-pub-like-icon-button" class="mdc-icon-button" data-ga-click-event="toggle-like" aria-pressed="false" title="Like this package"><img class="mdc-icon-button__icon" src="/static/hash-o6oemknr/img/like-inactive.svg" alt="liked status: inactive" width="18" height="18"/><img class="mdc-icon-button__icon mdc-icon-button__icon--on" src="/static/hash-o6oemknr/img/like-active.svg" alt="liked status: active" width="18" height="18"/></button><span class="likes-count"><span id="likes-count">7.3k</span></span></div></div></div></div></div></div><div class="detail-container"><div class="detail-lead"><div class="detail-metadata-toggle"><div class="detail-metadata-toggle-icon">→</div><h3 class="detail-lead-title">Metadata</h3></div><p class="detail-lead-text">Flutter Widgets that make it easy to implement the BLoC (Business Logic Component) design pattern. Built to be used with the bloc state management package.</p><p class="detail-lead-more"><a class="detail-metadata-toggle">More...</a></p></div></div><div class="detail-body"><div class="detail-tabs"><div class="detail-tabs-wide-header"><div class="detail-container"><ul class="detail-tabs-header"><li class="detail-tab tab-button detail-tab-readme-title -active">Readme</li><li class="detail-tab tab-link detail-tab-changelog-title"><a href="/packages/flutter_bloc/changelog" role="button">Changelog</a></li><li class="detail-tab tab-link detail-tab-example-title"><a href="/packages/flutter_bloc/example" role="button">Example</a></li><li class="detail-tab tab-link detail-tab-installing-title"><a href="/packages/flutter_bloc/install" role="button">Installing</a></li><li class="detail-tab tab-link detail-tab-versions-title"><a href="/packages/flutter_bloc/versions" role="button">Versions</a></li><li class="detail-tab tab-link detail-tab-analysis-title"><a href="/packages/flutter_bloc/score" role="button">Scores</a></li></ul></div></div><div class="detail-container detail-body-main"><div class="detail-tabs-content"><section class="tab-content detail-tab-readme-content -active markdown-body"><p align="right"> <a href="https://flutter.dev/docs/development/packages-and-plugins/favorites"><img src="https://raw.githubusercontent.com/felangel/bloc/master/assets/pub/flutter_favorite.png" width="100" alt="build"></a> </p> <p align="center"> <img src="https://raw.githubusercontent.com/felangel/bloc/master/assets/logos/flutter_bloc.png" height="100" alt="Flutter Bloc Package"> </p> <p align="center"> <a href="https://pub.dev/packages/flutter_bloc"><img src="https://img.shields.io/pub/v/flutter_bloc.svg" alt="Pub"></a> <a href="https://github.com/felangel/bloc/actions" rel="ugc"><img src="https://github.com/felangel/bloc/workflows/build/badge.svg" alt="build"></a> <a href="https://codecov.io/gh/felangel/bloc" rel="ugc"><img src="https://codecov.io/gh/felangel/Bloc/branch/master/graph/badge.svg" alt="codecov"></a> <a href="https://github.com/felangel/bloc" rel="ugc"><img src="https://img.shields.io/github/stars/felangel/bloc.svg?style=flat&logo=github&colorB=deeppink&label=stars" alt="Star on Github"></a> <a href="https://flutter.dev/docs/development/data-and-backend/state-mgmt/options#bloc--rx"><img src="https://img.shields.io/badge/flutter-website-deepskyblue.svg" alt="Flutter Website"></a> <a href="https://github.com/Solido/awesome-flutter#standard" rel="ugc"><img src="https://img.shields.io/badge/awesome-flutter-blue.svg?longCache=true" alt="Awesome Flutter"></a> <a href="https://fluttersamples.com" rel="ugc"><img src="https://img.shields.io/badge/flutter-samples-teal.svg?longCache=true" alt="Flutter Samples"></a> <a href="https://opensource.org/licenses/MIT" rel="ugc"><img src="https://img.shields.io/badge/license-MIT-purple.svg" alt="License: MIT"></a> <a href="https://discord.gg/bloc" rel="ugc"><img src="https://img.shields.io/discord/649708778631200778.svg?logo=discord&color=blue" alt="Discord"></a> <a href="https://github.com/felangel/bloc" rel="ugc"><img src="https://tinyurl.com/bloc-library" alt="Bloc Library"></a> </p> <hr> <p>Widgets that make it easy to integrate blocs and cubits into <a href="https://flutter.dev">Flutter</a>. Built to work with <a href="https://pub.dev/packages/bloc">package:bloc</a>.</p> <p><strong>Learn more at <a href="https://bloclibrary.dev" rel="ugc">bloclibrary.dev</a>!</strong></p> <p><em>*Note: All widgets exported by the <code>flutter_bloc</code> package integrate with both <code>Cubit</code> and <code>Bloc</code> instances.</em></p> <hr> <h2 class="hash-header" id="sponsors">Sponsors <a href="#sponsors" class="hash-link">#</a></h2> <p>Our top sponsors are shown below! [<a href="https://github.com/sponsors/felangel" rel="ugc">Become a Sponsor</a>]</p> <table> <tbody> <tr> <td align="center"> <a href="https://www.monterail.com/services/flutter-development/?utm_source=bloc&utm_medium=logo&utm_campaign=flutter" rel="ugc"><img src="https://raw.githubusercontent.com/felangel/bloc/master/assets/sponsors/monterail.png" width="225"></a> </td> <td align="center"> <a href="https://getstream.io/chat/flutter/tutorial/?utm_source=Github&utm_medium=Github_Repo_Content_Ad&utm_content=Developer&utm_campaign=Github_Jan2022_FlutterChat&utm_term=bloc" rel="ugc"><img src="https://raw.githubusercontent.com/felangel/bloc/master/assets/sponsors/stream.png" width="225"></a> </td> <td align="center"> <a href="https://www.miquido.com/flutter-development-company/?utm_source=github&utm_medium=sponsorship&utm_campaign=bloc-silver-tier&utm_term=flutter-development-company&utm_content=miquido-logo" rel="ugc"><img src="https://raw.githubusercontent.com/felangel/bloc/master/assets/sponsors/miquido.png" width="225"></a> </td> </tr> <tr> <td align="center"> <a href="https://bit.ly/parabeac_flutterbloc" rel="ugc"><img src="https://raw.githubusercontent.com/felangel/bloc/master/assets/sponsors/parabeac.png" width="225"></a> </td> <td align="center"> <a href="https://www.netguru.com/services/flutter-app-development?utm_campaign=%5BS%5D%5BMob%5D%20Flutter&utm_source=github&utm_medium=sponsorship&utm_term=bloclibrary" rel="ugc"><img src="https://raw.githubusercontent.com/felangel/bloc/master/assets/sponsors/netguru.png" width="225"></a> </td> <td align="center"> <a href="https://www.porada.app/" rel="ugc"><img src="https://raw.githubusercontent.com/felangel/bloc/master/assets/sponsors/porada.png" width="225"></a> </td> </tr> </tbody> </table> <hr> <h2 class="hash-header" id="usage">Usage <a href="#usage" class="hash-link">#</a></h2> <p>Lets take a look at how to use <code>BlocProvider</code> to provide a <code>CounterCubit</code> to a <code>CounterPage</code> and react to state changes with <code>BlocBuilder</code>.</p> <h3 class="hash-header" id="counter_cubitdart">counter_cubit.dart <a href="#counter_cubitdart" class="hash-link">#</a></h3> <pre><code class="language-dart">class CounterCubit extends Cubit<int> { CounterCubit() : super(0); void increment() => emit(state + 1); void decrement() => emit(state - 1); } </code></pre> <h3 class="hash-header" id="maindart">main.dart <a href="#maindart" class="hash-link">#</a></h3> <pre><code class="language-dart">void main() => runApp(CounterApp()); class CounterApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: BlocProvider( create: (_) => CounterCubit(), child: CounterPage(), ), ); } } </code></pre> <h3 class="hash-header" id="counter_pagedart">counter_page.dart <a href="#counter_pagedart" class="hash-link">#</a></h3> <pre><code class="language-dart">class CounterPage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Counter')), body: BlocBuilder<CounterCubit, int>( builder: (context, count) => Center(child: Text('$count')), ), floatingActionButton: Column( crossAxisAlignment: CrossAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end, children: <Widget>[ FloatingActionButton( child: const Icon(Icons.add), onPressed: () => context.read<CounterCubit>().increment(), ), const SizedBox(height: 4), FloatingActionButton( child: const Icon(Icons.remove), onPressed: () => context.read<CounterCubit>().decrement(), ), ], ), ); } } </code></pre> <p>At this point we have successfully separated our presentational layer from our business logic layer. Notice that the <code>CounterPage</code> widget knows nothing about what happens when a user taps the buttons. The widget simply notifies the <code>CounterCubit</code> that the user has pressed either the increment or decrement button.</p> <h2 class="hash-header" id="bloc-widgets">Bloc Widgets <a href="#bloc-widgets" class="hash-link">#</a></h2> <h3 class="hash-header" id="blocbuilder">BlocBuilder <a href="#blocbuilder" class="hash-link">#</a></h3> <p><strong>BlocBuilder</strong> is a Flutter widget which requires a <code>bloc</code> and a <code>builder</code> function. <code>BlocBuilder</code> handles building the widget in response to new states. <code>BlocBuilder</code> is very similar to <code>StreamBuilder</code> but has a more simple API to reduce the amount of boilerplate code needed. The <code>builder</code> function will potentially be called many times and should be a <a href="https://en.wikipedia.org/wiki/Pure_function" rel="ugc">pure function</a> that returns a widget in response to the state.</p> <p>See <code>BlocListener</code> if you want to "do" anything in response to state changes such as navigation, showing a dialog, etc...</p> <p>If the <code>bloc</code> parameter is omitted, <code>BlocBuilder</code> will automatically perform a lookup using <code>BlocProvider</code> and the current <code>BuildContext</code>.</p> <pre><code class="language-dart">BlocBuilder<BlocA, BlocAState>( builder: (context, state) { // return widget here based on BlocA's state } ) </code></pre> <p>Only specify the bloc if you wish to provide a bloc that will be scoped to a single widget and isn't accessible via a parent <code>BlocProvider</code> and the current <code>BuildContext</code>.</p> <pre><code class="language-dart">BlocBuilder<BlocA, BlocAState>( bloc: blocA, // provide the local bloc instance builder: (context, state) { // return widget here based on BlocA's state } ) </code></pre> <p>For fine-grained control over when the <code>builder</code> function is called an optional <code>buildWhen</code> can be provided. <code>buildWhen</code> takes the previous bloc state and current bloc state and returns a boolean. If <code>buildWhen</code> returns true, <code>builder</code> will be called with <code>state</code> and the widget will rebuild. If <code>buildWhen</code> returns false, <code>builder</code> will not be called with <code>state</code> and no rebuild will occur.</p> <pre><code class="language-dart">BlocBuilder<BlocA, BlocAState>( buildWhen: (previousState, state) { // return true/false to determine whether or not // to rebuild the widget with state }, builder: (context, state) { // return widget here based on BlocA's state } ) </code></pre> <h3 class="hash-header" id="blocselector">BlocSelector <a href="#blocselector" class="hash-link">#</a></h3> <p><strong>BlocSelector</strong> is a Flutter widget which is analogous to <code>BlocBuilder</code> but allows developers to filter updates by selecting a new value based on the current bloc state. Unnecessary builds are prevented if the selected value does not change. The selected value must be immutable in order for <code>BlocSelector</code> to accurately determine whether <code>builder</code> should be called again.</p> <p>If the <code>bloc</code> parameter is omitted, <code>BlocSelector</code> will automatically perform a lookup using <code>BlocProvider</code> and the current <code>BuildContext</code>.</p> <pre><code class="language-dart">BlocSelector<BlocA, BlocAState, SelectedState>( selector: (state) { // return selected state based on the provided state. }, builder: (context, state) { // return widget here based on the selected state. }, ) </code></pre> <h3 class="hash-header" id="blocprovider">BlocProvider <a href="#blocprovider" class="hash-link">#</a></h3> <p><strong>BlocProvider</strong> is a Flutter widget which provides a bloc to its children via <code>BlocProvider.of<T>(context)</code>. It is used as a dependency injection (DI) widget so that a single instance of a bloc can be provided to multiple widgets within a subtree.</p> <p>In most cases, <code>BlocProvider</code> should be used to create new blocs which will be made available to the rest of the subtree. In this case, since <code>BlocProvider</code> is responsible for creating the bloc, it will automatically handle closing it.</p> <pre><code class="language-dart">BlocProvider( create: (BuildContext context) => BlocA(), child: ChildA(), ); </code></pre> <p>By default, BlocProvider will create the bloc lazily, meaning <code>create</code> will get executed when the bloc is looked up via <code>BlocProvider.of<BlocA>(context)</code>.</p> <p>To override this behavior and force <code>create</code> to be run immediately, <code>lazy</code> can be set to <code>false</code>.</p> <pre><code class="language-dart">BlocProvider( lazy: false, create: (BuildContext context) => BlocA(), child: ChildA(), ); </code></pre> <p>In some cases, <code>BlocProvider</code> can be used to provide an existing bloc to a new portion of the widget tree. This will be most commonly used when an existing <code>bloc</code> needs to be made available to a new route. In this case, <code>BlocProvider</code> will not automatically close the bloc since it did not create it.</p> <pre><code class="language-dart">BlocProvider.value( value: BlocProvider.of<BlocA>(context), child: ScreenA(), ); </code></pre> <p>then from either <code>ChildA</code>, or <code>ScreenA</code> we can retrieve <code>BlocA</code> with:</p> <pre><code class="language-dart">// with extensions context.read<BlocA>(); // without extensions BlocProvider.of<BlocA>(context); </code></pre> <p>The above snippets result in a one time lookup and the widget will not be notified of changes. To retrieve the instance and subscribe to subsequent state changes use:</p> <pre><code class="language-dart">// with extensions context.watch<BlocA>(); // without extensions BlocProvider.of<BlocA>(context, listen: true); </code></pre> <p>In addition, <code>context.select</code> can be used to retrieve part of a state and react to changes only when the selected part changes.</p> <pre><code class="language-dart">final isPositive = context.select((CounterBloc b) => b.state >= 0); </code></pre> <p>The snippet above will only rebuild if the state of the <code>CounterBloc</code> changes from positive to negative or vice versa and is functionally identical to using a <code>BlocSelector</code>.</p> <h3 class="hash-header" id="multiblocprovider">MultiBlocProvider <a href="#multiblocprovider" class="hash-link">#</a></h3> <p><strong>MultiBlocProvider</strong> is a Flutter widget that merges multiple <code>BlocProvider</code> widgets into one. <code>MultiBlocProvider</code> improves the readability and eliminates the need to nest multiple <code>BlocProviders</code>. By using <code>MultiBlocProvider</code> we can go from:</p> <pre><code class="language-dart">BlocProvider<BlocA>( create: (BuildContext context) => BlocA(), child: BlocProvider<BlocB>( create: (BuildContext context) => BlocB(), child: BlocProvider<BlocC>( create: (BuildContext context) => BlocC(), child: ChildA(), ) ) ) </code></pre> <p>to:</p> <pre><code class="language-dart">MultiBlocProvider( providers: [ BlocProvider<BlocA>( create: (BuildContext context) => BlocA(), ), BlocProvider<BlocB>( create: (BuildContext context) => BlocB(), ), BlocProvider<BlocC>( create: (BuildContext context) => BlocC(), ), ], child: ChildA(), ) </code></pre> <h3 class="hash-header" id="bloclistener">BlocListener <a href="#bloclistener" class="hash-link">#</a></h3> <p><strong>BlocListener</strong> is a Flutter widget which takes a <code>BlocWidgetListener</code> and an optional <code>bloc</code> and invokes the <code>listener</code> in response to state changes in the bloc. It should be used for functionality that needs to occur once per state change such as navigation, showing a <code>SnackBar</code>, showing a <code>Dialog</code>, etc...</p> <p><code>listener</code> is only called once for each state change (<strong>NOT</strong> including the initial state) unlike <code>builder</code> in <code>BlocBuilder</code> and is a <code>void</code> function.</p> <p>If the bloc parameter is omitted, <code>BlocListener</code> will automatically perform a lookup using <code>BlocProvider</code> and the current <code>BuildContext</code>.</p> <pre><code class="language-dart">BlocListener<BlocA, BlocAState>( listener: (context, state) { // do stuff here based on BlocA's state }, child: Container(), ) </code></pre> <p>Only specify the bloc if you wish to provide a bloc that is otherwise not accessible via <code>BlocProvider</code> and the current <code>BuildContext</code>.</p> <pre><code class="language-dart">BlocListener<BlocA, BlocAState>( bloc: blocA, listener: (context, state) { // do stuff here based on BlocA's state } ) </code></pre> <p>For fine-grained control over when the <code>listener</code> function is called an optional <code>listenWhen</code> can be provided. <code>listenWhen</code> takes the previous bloc state and current bloc state and returns a boolean. If <code>listenWhen</code> returns true, <code>listener</code> will be called with <code>state</code>. If <code>listenWhen</code> returns false, <code>listener</code> will not be called with <code>state</code>.</p> <pre><code class="language-dart">BlocListener<BlocA, BlocAState>( listenWhen: (previousState, state) { // return true/false to determine whether or not // to call listener with state }, listener: (context, state) { // do stuff here based on BlocA's state }, child: Container(), ) </code></pre> <h3 class="hash-header" id="multibloclistener">MultiBlocListener <a href="#multibloclistener" class="hash-link">#</a></h3> <p><strong>MultiBlocListener</strong> is a Flutter widget that merges multiple <code>BlocListener</code> widgets into one. <code>MultiBlocListener</code> improves the readability and eliminates the need to nest multiple <code>BlocListeners</code>. By using <code>MultiBlocListener</code> we can go from:</p> <pre><code class="language-dart">BlocListener<BlocA, BlocAState>( listener: (context, state) {}, child: BlocListener<BlocB, BlocBState>( listener: (context, state) {}, child: BlocListener<BlocC, BlocCState>( listener: (context, state) {}, child: ChildA(), ), ), ) </code></pre> <p>to:</p> <pre><code class="language-dart">MultiBlocListener( listeners: [ BlocListener<BlocA, BlocAState>( listener: (context, state) {}, ), BlocListener<BlocB, BlocBState>( listener: (context, state) {}, ), BlocListener<BlocC, BlocCState>( listener: (context, state) {}, ), ], child: ChildA(), ) </code></pre> <h3 class="hash-header" id="blocconsumer">BlocConsumer <a href="#blocconsumer" class="hash-link">#</a></h3> <p><strong>BlocConsumer</strong> exposes a <code>builder</code> and <code>listener</code> in order react to new states. <code>BlocConsumer</code> is analogous to a nested <code>BlocListener</code> and <code>BlocBuilder</code> but reduces the amount of boilerplate needed. <code>BlocConsumer</code> should only be used when it is necessary to both rebuild UI and execute other reactions to state changes in the <code>bloc</code>. <code>BlocConsumer</code> takes a required <code>BlocWidgetBuilder</code> and <code>BlocWidgetListener</code> and an optional <code>bloc</code>, <code>BlocBuilderCondition</code>, and <code>BlocListenerCondition</code>.</p> <p>If the <code>bloc</code> parameter is omitted, <code>BlocConsumer</code> will automatically perform a lookup using <code>BlocProvider</code> and the current <code>BuildContext</code>.</p> <pre><code class="language-dart">BlocConsumer<BlocA, BlocAState>( listener: (context, state) { // do stuff here based on BlocA's state }, builder: (context, state) { // return widget here based on BlocA's state } ) </code></pre> <p>An optional <code>listenWhen</code> and <code>buildWhen</code> can be implemented for more granular control over when <code>listener</code> and <code>builder</code> are called. The <code>listenWhen</code> and <code>buildWhen</code> will be invoked on each <code>bloc</code> <code>state</code> change. They each take the previous <code>state</code> and current <code>state</code> and must return a <code>bool</code> which determines whether or not the <code>builder</code> and/or <code>listener</code> function will be invoked. The previous <code>state</code> will be initialized to the <code>state</code> of the <code>bloc</code> when the <code>BlocConsumer</code> is initialized. <code>listenWhen</code> and <code>buildWhen</code> are optional and if they aren't implemented, they will default to <code>true</code>.</p> <pre><code class="language-dart">BlocConsumer<BlocA, BlocAState>( listenWhen: (previous, current) { // return true/false to determine whether or not // to invoke listener with state }, listener: (context, state) { // do stuff here based on BlocA's state }, buildWhen: (previous, current) { // return true/false to determine whether or not // to rebuild the widget with state }, builder: (context, state) { // return widget here based on BlocA's state } ) </code></pre> <h3 class="hash-header" id="repositoryprovider">RepositoryProvider <a href="#repositoryprovider" class="hash-link">#</a></h3> <p><strong>RepositoryProvider</strong> is a Flutter widget which provides a repository to its children via <code>RepositoryProvider.of<T>(context)</code>. It is used as a dependency injection (DI) widget so that a single instance of a repository can be provided to multiple widgets within a subtree. <code>BlocProvider</code> should be used to provide blocs whereas <code>RepositoryProvider</code> should only be used for repositories.</p> <pre><code class="language-dart">RepositoryProvider( create: (context) => RepositoryA(), child: ChildA(), ); </code></pre> <p>then from <code>ChildA</code> we can retrieve the <code>Repository</code> instance with:</p> <pre><code class="language-dart">// with extensions context.read<RepositoryA>(); // without extensions RepositoryProvider.of<RepositoryA>(context) </code></pre> <h3 class="hash-header" id="multirepositoryprovider">MultiRepositoryProvider <a href="#multirepositoryprovider" class="hash-link">#</a></h3> <p><strong>MultiRepositoryProvider</strong> is a Flutter widget that merges multiple <code>RepositoryProvider</code> widgets into one. <code>MultiRepositoryProvider</code> improves the readability and eliminates the need to nest multiple <code>RepositoryProvider</code>. By using <code>MultiRepositoryProvider</code> we can go from:</p> <pre><code class="language-dart">RepositoryProvider<RepositoryA>( create: (context) => RepositoryA(), child: RepositoryProvider<RepositoryB>( create: (context) => RepositoryB(), child: RepositoryProvider<RepositoryC>( create: (context) => RepositoryC(), child: ChildA(), ) ) ) </code></pre> <p>to:</p> <pre><code class="language-dart">MultiRepositoryProvider( providers: [ RepositoryProvider<RepositoryA>( create: (context) => RepositoryA(), ), RepositoryProvider<RepositoryB>( create: (context) => RepositoryB(), ), RepositoryProvider<RepositoryC>( create: (context) => RepositoryC(), ), ], child: ChildA(), ) </code></pre> <h2 class="hash-header" id="gallery">Gallery <a href="#gallery" class="hash-link">#</a></h2> <div> <table> <tbody><tr> <td> <a href="https://bloclibrary.dev/tutorials/flutter-counter" rel="ugc"> <img src="https://raw.githubusercontent.com/felangel/bloc/master/assets/examples/flutter_counter.gif" width="200"> </a> </td> <td> <a href="https://bloclibrary.dev/tutorials/flutter-infinite-list" rel="ugc"> <img src="https://raw.githubusercontent.com/felangel/bloc/master/assets/examples/flutter_infinite_list.gif" width="200"> </a> </td> <td> <a href="https://bloclibrary.dev/tutorials/flutter-login" rel="ugc"> <img src="https://raw.githubusercontent.com/felangel/bloc/master/assets/examples/flutter_firebase_login.gif" width="200"> </a> </td> </tr> <tr> <td> <a href="https://bloclibrary.dev/tutorials/github-search" rel="ugc"> <img src="https://raw.githubusercontent.com/felangel/bloc/master/assets/examples/flutter_github_search.gif" width="200"> </a> </td> <td> <a href="https://bloclibrary.dev/tutorials/flutter-weather" rel="ugc"> <img src="https://raw.githubusercontent.com/felangel/bloc/master/assets/examples/flutter_weather.gif" width="200"> </a> </td> <td> <a href="https://bloclibrary.dev/tutorials/flutter-todos" rel="ugc"> <img src="https://raw.githubusercontent.com/felangel/bloc/master/assets/examples/flutter_todos.gif" width="200"> </a> </td> </tr> </tbody></table> </div> <h2 class="hash-header" id="examples">Examples <a href="#examples" class="hash-link">#</a></h2> <ul> <li><a href="https://bloclibrary.dev/tutorials/flutter-counter" rel="ugc">Counter</a> - an example of how to create a <code>CounterBloc</code> to implement the classic Flutter Counter app.</li> <li><a href="https://github.com/felangel/bloc/tree/master/examples/flutter_form_validation" rel="ugc">Form Validation</a> - an example of how to use the <code>bloc</code> and <code>flutter_bloc</code> packages to implement form validation.</li> <li><a href="https://github.com/felangel/bloc/tree/master/examples/flutter_bloc_with_stream" rel="ugc">Bloc with Stream</a> - an example of how to hook up a <code>bloc</code> to a <code>Stream</code> and update the UI in response to data from the <code>Stream</code>.</li> <li><a href="https://github.com/felangel/bloc/tree/master/examples/flutter_complex_list" rel="ugc">Complex List</a> - an example of how to manage a list of items and asynchronously delete items one at a time using <code>bloc</code> and <code>flutter_bloc</code>.</li> <li><a href="https://bloclibrary.dev/tutorials/flutter-infinite-list" rel="ugc">Infinite List</a> - an example of how to use the <code>bloc</code> and <code>flutter_bloc</code> packages to implement an infinite scrolling list.</li> <li><a href="https://bloclibrary.dev/tutorials/flutter-login" rel="ugc">Login Flow</a> - an example of how to use the <code>bloc</code> and <code>flutter_bloc</code> packages to implement a Login Flow.</li> <li><a href="https://bloclibrary.dev/tutorials/flutter-firebase-login" rel="ugc">Firebase Login</a> - an example of how to use the <code>bloc</code> and <code>flutter_bloc</code> packages to implement login via Firebase.</li> <li><a href="https://bloclibrary.dev/tutorials/github-search" rel="ugc">Github Search</a> - an example of how to create a Github Search Application using the <code>bloc</code> and <code>flutter_bloc</code> packages.</li> <li><a href="https://bloclibrary.dev/tutorials/flutter-weather" rel="ugc">Weather</a> - an example of how to create a Weather Application using the <code>bloc</code> and <code>flutter_bloc</code> packages. The app uses a <code>RefreshIndicator</code> to implement "pull-to-refresh" as well as dynamic theming.</li> <li><a href="https://bloclibrary.dev/tutorials/flutter-todos" rel="ugc">Todos</a> - an example of how to create a Todos Application using the <code>bloc</code> and <code>flutter_bloc</code> packages.</li> <li><a href="https://bloclibrary.dev/tutorials/flutter-timer" rel="ugc">Timer</a> - an example of how to create a Timer using the <code>bloc</code> and <code>flutter_bloc</code> packages.</li> <li><a href="https://github.com/felangel/bloc/tree/master/examples/flutter_shopping_cart" rel="ugc">Shopping Cart</a> - an example of how to create a Shopping Cart Application using the <code>bloc</code> and <code>flutter_bloc</code> packages based on <a href="https://github.com/flutter/samples/tree/master/provider_shopper" rel="ugc">flutter samples</a>.</li> <li><a href="https://github.com/felangel/bloc/tree/master/examples/flutter_dynamic_form" rel="ugc">Dynamic Form</a> - an example of how to use the <code>bloc</code> and <code>flutter_bloc</code> packages to implement a dynamic form which pulls data from a repository.</li> <li><a href="https://github.com/felangel/bloc/tree/master/examples/flutter_wizard" rel="ugc">Wizard</a> - an example of how to build a multi-step wizard using the <code>bloc</code> and <code>flutter_bloc</code> packages.</li> <li><a href="https://github.com/felangel/fluttersaurus" rel="ugc">Fluttersaurus</a> - an example of how to use the <code>bloc</code> and <code>flutter_bloc</code> packages to create a thesuarus app -- made for Bytconf Flutter 2020.</li> <li><a href="https://github.com/flutter/photobooth" rel="ugc">I/O Photo Booth</a> - an example of how to use the <code>bloc</code> and <code>flutter_bloc</code> packages to create a virtual photo booth web app -- made for Google I/O 2021.</li> <li><a href="https://github.com/flutter/pinball" rel="ugc">I/O Pinball</a> - an example of how to use the <code>bloc</code> and <code>flutter_bloc</code> packages to create a pinball web app -- made for Google I/O 2022.</li> </ul> <h2 class="hash-header" id="dart-versions">Dart Versions <a href="#dart-versions" class="hash-link">#</a></h2> <ul> <li>Dart 2: >= 2.12</li> </ul> <h2 class="hash-header" id="maintainers">Maintainers <a href="#maintainers" class="hash-link">#</a></h2> <ul> <li><a href="https://github.com/felangel" rel="ugc">Felix Angelov</a></li> </ul> </section></div></div></div><aside class="detail-info-box"><a class="packages-scores" href="/packages/flutter_bloc/score"><div class="packages-score packages-score-like"><div class="packages-score-value -has-value"><span class="packages-score-value-number">7315</span><span class="packages-score-value-sign"></span></div><div class="packages-score-label">likes</div></div><div class="packages-score packages-score-health"><div class="packages-score-value -has-value"><span class="packages-score-value-number">160</span><span class="packages-score-value-sign"></span></div><div class="packages-score-label">pub points</div></div><div class="packages-score packages-score-popularity"><div class="packages-score-value -has-value"><span class="packages-score-value-number">100</span><span class="packages-score-value-sign">%</span></div><div class="packages-score-label">popularity</div></div></a><div class="detail-screenshot-thumbnail"><div class="thumbnail-container" data-thumbnail="/packages/flutter_bloc/versions/8.1.6/gen-res/gen/logo.webp" data-thumbnail-descriptions-json="["The flutter bloc package logo."]" data-ga-click-event="screenshot-thumbnail-click"><img class="thumbnail-image" src="/packages/flutter_bloc/versions/8.1.6/gen-res/gen/190x190/logo.webp" alt="screenshot" title="View screenshots" tabindex="0"/></div><img class="collections-icon" src="/static/hash-o6oemknr/img/collections_white_24dp.svg" alt="" width="30" height="30" role="presentation"/></div><h3 class="title">Publisher</h3><p><a href="/publishers/bloclibrary.dev"><img class="-pub-publisher-shield filter-invert-on-dark" src="/static/hash-o6oemknr/img/material-icon-verified.svg" alt="verified publisher" width="14" height="14" title="Published by a pub.dev verified publisher"/>bloclibrary.dev</a></p><h3 class="title pkg-infobox-metadata">Metadata</h3><p>Flutter Widgets that make it easy to implement the BLoC (Business Logic Component) design pattern. Built to be used with the bloc state management package.</p><p><a class="link" href="https://bloclibrary.dev" rel="ugc">Homepage</a><br/><a class="link" href="https://github.com/felangel/bloc/tree/master/packages/flutter_bloc" rel="ugc">Repository (GitHub)</a><br/><a class="link" href="https://github.com/felangel/bloc/issues" rel="ugc">View/report issues</a><br/><a class="link" href="https://github.com/felangel/bloc/blob/master/CONTRIBUTING.md" rel="ugc">Contributing</a><br/></p><h3 class="title">Topics</h3><p><a href="/packages?q=topic%3Abloc" rel="nofollow">#bloc</a> <a href="/packages?q=topic%3Astate-management" rel="nofollow">#state-management</a></p><h3 class="title">Documentation</h3><p><a class="link" href="https://bloclibrary.dev/getting-started" rel="ugc">Documentation</a><br/><a class="link" href="/documentation/flutter_bloc/latest/">API reference</a><br/></p><h3 class="title">License</h3><p><img class="inline-icon-img filter-invert-on-dark" src="/static/hash-o6oemknr/img/material-icon-balance.svg" alt="" width="14" height="14" role="presentation"/>MIT (<a href="/packages/flutter_bloc/license">license</a>)</p><h3 class="title">Dependencies</h3><p><a href="/packages/bloc" title="^8.1.1">bloc</a>, <a href="https://api.flutter.dev/">flutter</a>, <a href="/packages/provider" title="^6.0.0">provider</a></p><h3 class="title">More</h3><p><a href="/packages?q=dependency%3Aflutter_bloc" rel="nofollow">Packages that depend on flutter_bloc</a></p></aside></div><script type="application/ld+json">{"@context":"http\u003a\u002f\u002fschema.org","@type":"SoftwareSourceCode","name":"flutter\u005fbloc","version":"8.1.6","description":"flutter\u005fbloc - Flutter Widgets that make it easy to implement the BLoC \u0028Business Logic Component\u0029 design pattern. Built to be used with the bloc state management package.","url":"https\u003a\u002f\u002fpub.dev\u002fpackages\u002fflutter\u005fbloc","dateCreated":"2018-10-23T01\u003a25\u003a21.104355Z","dateModified":"2024-06-11T04\u003a40\u003a34.623683Z","programmingLanguage":"Dart","image":"https\u003a\u002f\u002fpub.dev\u002fstatic\u002fimg\u002fpub-dev-icon-cover-image.png","license":"https\u003a\u002f\u002fpub.dev\u002fpackages\u002fflutter\u005fbloc\u002flicense"}</script></div><div class="detail-metadata"><h3 class="detail-metadata-title"><span class="detail-metadata-toggle">←</span> Metadata</h3><div class="detail-info-box"><a class="packages-scores" href="/packages/flutter_bloc/score"><div class="packages-score packages-score-like"><div class="packages-score-value -has-value"><span class="packages-score-value-number">7315</span><span class="packages-score-value-sign"></span></div><div class="packages-score-label">likes</div></div><div class="packages-score packages-score-health"><div class="packages-score-value -has-value"><span class="packages-score-value-number">160</span><span class="packages-score-value-sign"></span></div><div class="packages-score-label">pub points</div></div><div class="packages-score packages-score-popularity"><div class="packages-score-value -has-value"><span class="packages-score-value-number">100</span><span class="packages-score-value-sign">%</span></div><div class="packages-score-label">popularity</div></div></a><div class="detail-screenshot-thumbnail"><div class="thumbnail-container" data-thumbnail="/packages/flutter_bloc/versions/8.1.6/gen-res/gen/logo.webp" data-thumbnail-descriptions-json="["The flutter bloc package logo."]" data-ga-click-event="screenshot-thumbnail-click"><img class="thumbnail-image" src="/packages/flutter_bloc/versions/8.1.6/gen-res/gen/190x190/logo.webp" alt="screenshot" title="View screenshots" tabindex="0"/></div><img class="collections-icon" src="/static/hash-o6oemknr/img/collections_white_24dp.svg" alt="" width="30" height="30" role="presentation"/></div><h3 class="title">Publisher</h3><p><a href="/publishers/bloclibrary.dev"><img class="-pub-publisher-shield filter-invert-on-dark" src="/static/hash-o6oemknr/img/material-icon-verified.svg" alt="verified publisher" width="14" height="14" title="Published by a pub.dev verified publisher"/>bloclibrary.dev</a></p><h3 class="title pkg-infobox-metadata">Metadata</h3><p>Flutter Widgets that make it easy to implement the BLoC (Business Logic Component) design pattern. Built to be used with the bloc state management package.</p><p><a class="link" href="https://bloclibrary.dev" rel="ugc">Homepage</a><br/><a class="link" href="https://github.com/felangel/bloc/tree/master/packages/flutter_bloc" rel="ugc">Repository (GitHub)</a><br/><a class="link" href="https://github.com/felangel/bloc/issues" rel="ugc">View/report issues</a><br/><a class="link" href="https://github.com/felangel/bloc/blob/master/CONTRIBUTING.md" rel="ugc">Contributing</a><br/></p><h3 class="title">Topics</h3><p><a href="/packages?q=topic%3Abloc" rel="nofollow">#bloc</a> <a href="/packages?q=topic%3Astate-management" rel="nofollow">#state-management</a></p><h3 class="title">Documentation</h3><p><a class="link" href="https://bloclibrary.dev/getting-started" rel="ugc">Documentation</a><br/><a class="link" href="/documentation/flutter_bloc/latest/">API reference</a><br/></p><h3 class="title">License</h3><p><img class="inline-icon-img filter-invert-on-dark" src="/static/hash-o6oemknr/img/material-icon-balance.svg" alt="" width="14" height="14" role="presentation"/>MIT (<a href="/packages/flutter_bloc/license">license</a>)</p><h3 class="title">Dependencies</h3><p><a href="/packages/bloc" title="^8.1.1">bloc</a>, <a href="https://api.flutter.dev/">flutter</a>, <a href="/packages/provider" title="^6.0.0">provider</a></p><h3 class="title">More</h3><p><a href="/packages?q=dependency%3Aflutter_bloc" rel="nofollow">Packages that depend on flutter_bloc</a></p></div><p class="detail-lead-back"><a class="detail-metadata-toggle">Back</a></p></div><div id="-screenshot-carousel" class="carousel"><fab id="-carousel-prev" class="mdc-fab carousel-prev carousel-nav" data-mdc-auto-init="MDCRipple" title="Previous" data-ga-click-event="screenshot-carousel-prev-click" tabindex="0"><div class="mdc-fab__ripple"></div><img class="mdc-fab__icon" src="/static/hash-o6oemknr/img/keyboard_arrow_left.svg" alt="previous" width="24" height="24" aria-hidden="true"/></fab><div id="-image-container" class="image-container"></div><fab id="-carousel-next" class="mdc-fab carousel-next carousel-nav" data-mdc-auto-init="MDCRipple" title="Next" data-ga-click-event="screenshot-carousel-next-click" tabindex="0"><div class="mdc-fab__ripple"></div><img class="mdc-fab__icon" src="/static/hash-o6oemknr/img/keyboard_arrow_right.svg" alt="next" width="24" height="24" aria-hidden="true"/></fab><p id="-screenshot-description" class="screenshot-description"></p></div></main><footer class="site-footer"><a class="link" href="https://dart.dev/">Dart language</a><a class="link sep" href="/report?subject=package%3Aflutter_bloc&url=https%3A%2F%2Fpub.dev%2Fpackages%2Fflutter_bloc">Report package</a><a class="link sep" href="/policy">Policy</a><a class="link sep" href="https://www.google.com/intl/en/policies/terms/">Terms</a><a class="link sep" href="https://developers.google.com/terms/">API Terms</a><a class="link sep" href="/security">Security</a><a class="link sep" href="https://www.google.com/intl/en/policies/privacy/">Privacy</a><a class="link sep" href="/help">Help</a><a class="link icon sep" href="/feed.atom"><img class="inline-icon" src="/static/hash-o6oemknr/img/rss-feed-icon.svg" alt="RSS" width="20" height="20" title="RSS/atom feed"/></a><a class="link icon github_issue" href="https://github.com/dart-lang/pub-dev/issues/new"><img class="inline-icon" src="/static/hash-o6oemknr/img/bug-report-white-96px.png" alt="bug report" width="20" height="20" title="Report an issue with this site"/></a></footer><script src="/static/hash-o6oemknr/highlight/highlight-with-init.js" defer="defer"></script></body></html>