1- [ Simple example] ( https://github.com/hoc081098/flutter_bloc_pattern/tree/master/example/counter ) a port of the standard "Counter Button" example from Flutter.
1+ # flutter_bloc_pattern
2+
3+ Base class, BLoC provider and ` rxdart ` builder for BLoC pattern in Flutter.
4+
5+ [ ![ Flutter test] ( https://github.com/hoc081098/flutter_bloc_pattern/workflows/Flutter%20test/badge.svg )] ( https://github.com/hoc081098/flutter_bloc_pattern/actions )
6+ [ ![ Pub] ( https://img.shields.io/pub/v/flutter_bloc_pattern.svg )] ( https://pub.dev/packages/flutter_bloc_pattern )
7+ [ ![ Pub] ( https://img.shields.io/pub/v/flutter_bloc_pattern?include_prereleases )] ( https://pub.dev/packages/flutter_bloc_pattern )
8+ [ ![ codecov] ( https://codecov.io/gh/hoc081098/flutter_bloc_pattern/branch/master/graph/badge.svg?token=yhrC5lmOqu )] ( https://codecov.io/gh/hoc081098/flutter_bloc_pattern )
9+ [ ![ GitHub] ( https://img.shields.io/github/license/hoc081098/flutter_bloc_pattern?color=4EB1BA )] ( https://opensource.org/licenses/MIT )
10+ [ ![ Style] ( https://img.shields.io/badge/style-pedantic-40c4ff.svg )] ( https://github.com/dart-lang/pedantic )
11+
12+ ## Getting Started
13+
14+ ### 1. Add this to your package's pubspec.yaml file
15+
16+ ``` yaml
17+ dependencies :
18+ flutter_bloc_pattern : <latest_version>
19+ ` ` `
20+
21+ ### 2. Implements BaseBloc
22+
23+ ` ` ` dart
24+ import 'package:disposebag/disposebag.dart';
25+ import 'package:flutter_bloc_pattern/flutter_bloc_pattern.dart';
26+ import 'package:rxdart_ext/rxdart_ext.dart';
27+
28+ class MyBloc implements BaseBloc {
29+ StateStream<String> get stream;
30+
31+ @override
32+ void dispose() {}
33+ }
34+ ```
35+
36+ ### 3. Consume BLoC
37+
38+ ``` dart
39+ final bloc = BlocProvider.of<MyBloc>(context);
40+ return RxStreamBuilder<String>(
41+ stream: bloc.stream,
42+ builder: (context, state) {
43+ return ...;
44+ },
45+ );
46+ ```
47+
48+ ## Example: A port of the standard "Counter Button" example from Flutter
49+
50+ ### 1. File ` counter_bloc.dart `
251
3- ### 1. File ` counter_bloc.dart ` :
452``` dart
553import 'dart:async';
654
@@ -37,117 +85,34 @@ class CounterBloc extends DisposeCallbackBaseBloc {
3785}
3886```
3987
40- ### 2. File ` main.dart ` :
88+ ### 2. File ` main.dart `
89+
4190``` dart
4291import 'package:example/bloc.dart';
4392import 'package:flutter/material.dart';
4493import 'package:flutter_bloc_pattern/flutter_bloc_pattern.dart';
4594
46- void main() => runApp(MyApp());
47-
48- class MyApp extends StatelessWidget {
49- @override
50- Widget build(BuildContext context) {
51- return MaterialApp(
52- title: 'Flutter bloc pattern',
53- theme: ThemeData(
54- primarySwatch: Colors.blue,
55- ),
56- home: StartPage(),
57- );
58- }
59- }
60-
61- class StartPage extends StatelessWidget {
62- @override
63- Widget build(BuildContext context) {
64- return Container(
65- child: Center(
66- child: TextButton(
67- onPressed: () => Navigator.of(context).push(
68- MaterialPageRoute(
69- builder: (context) {
70- return BlocProvider<CounterBloc>(
71- child: MyHomePage(),
72- initBloc: () => CounterBloc(),
73- );
74- },
75- ),
76- ),
77- child: Text('GO TO HOME'),
78- ),
79- ),
80- );
81- }
82- }
83-
84- class MyHomePage extends StatefulWidget {
85- @override
86- _MyHomePageState createState() => _MyHomePageState();
87- }
88-
89- class _MyHomePageState extends State<MyHomePage> {
90- @override
91- Widget build(BuildContext context) {
92- return Scaffold(
93- appBar: AppBar(
94- title: Text('Home page'),
95- ),
96- body: Center(
97- child: Column(
98- mainAxisAlignment: MainAxisAlignment.center,
99- children: const <Widget>[
100- Text('You have pushed the button this many times:'),
101- TextCounter1(),
102- TextCounter2(),
103- ],
104- ),
105- ),
106- floatingActionButton: const IncrementButton(),
107- );
108- }
109- }
110-
11195class TextCounter1 extends StatelessWidget {
112- const TextCounter1({Key? key}) : super( key: key );
96+ const TextCounter1({super. key} );
11397
11498 @override
11599 Widget build(BuildContext context) {
116100 final bloc = BlocProvider.of<CounterBloc>(context);
117101
118102 return RxStreamBuilder<int>(
119103 stream: bloc.state,
120- builder: (context, data) {
121- return Text(
122- 'COUNTER 1: $data',
123- style: Theme.of(context).textTheme.headline4,
124- );
125- },
126- );
127- }
128- }
129-
130- class TextCounter2 extends StatelessWidget {
131- const TextCounter2({Key? key}) : super(key: key);
132-
133- @override
134- Widget build(BuildContext context) {
135- final bloc = context.bloc<CounterBloc>();
136-
137- return RxStreamBuilder<int>(
138- stream: bloc.state,
139- builder: (context, data) {
104+ builder: (context, state) {
140105 return Text(
141- 'COUNTER 2 : $data ',
142- style: Theme.of(context).textTheme.headline4 ,
106+ 'COUNTER 1 : $state ',
107+ style: Theme.of(context).textTheme.titleLarge ,
143108 );
144109 },
145110 );
146111 }
147112}
148113
149114class IncrementButton extends StatelessWidget {
150- const IncrementButton({Key? key}) : super( key: key );
115+ const IncrementButton({super. key} );
151116
152117 @override
153118 Widget build(BuildContext context) {
@@ -156,7 +121,7 @@ class IncrementButton extends StatelessWidget {
156121 return FloatingActionButton(
157122 onPressed: bloc.increment,
158123 tooltip: 'Increment',
159- child: Icon(Icons.add),
124+ child: const Icon(Icons.add),
160125 );
161126 }
162127}
0 commit comments