In the following tutorial, we’re going to build a Counter in Flutter using the Bloc library.
We’ll start off by creating a brand new Flutter project
flutter create flutter_counter
We can then go ahead and replace the contents of pubspec.yaml
with
name: flutter_counter description: A new Flutter project. publish_to: "none" # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: sdk: ">=2.7.0 <3.0.0" dependencies: flutter: sdk: flutter bloc: ^6.1.0 flutter_bloc: ^6.1.0 dev_dependencies: flutter_test: sdk: flutter bloc_test: ^7.1.0 mockito: ^4.0.0 integration_test: ^1.0.0 flutter: uses-material-design: true
and then install all of our dependencies
flutter packages get
├── lib │ ├── app.dart │ ├── counter │ │ ├── counter.dart │ │ ├── cubit │ │ │ └── counter_cubit.dart │ │ └── view │ │ ├── counter_page.dart │ │ └── counter_view.dart │ ├── counter_observer.dart │ └── main.dart ├── pubspec.lock ├── pubspec.yaml
The application uses a feature-driven directory structure. This project structure enables us to scale the project by having self-contained features. In this example we will only have a single feature (the counter itself) but in more complex applications we can have hundreds of different features.
The first thing we’re going to take a look at is how to create a BlocObserver
which will help us observe all state changes in the application.
Let’s create lib/counter_observer.dart
:
import 'package:bloc/bloc.dart'; /// {@template counter_observer} /// [BlocObserver] for the counter application which /// observes all [Cubit] state changes. /// {@endtemplate} class CounterObserver extends BlocObserver { @override void onChange(Cubit cubit, Change change) { print('${cubit.runtimeType} $change'); super.onChange(cubit, change); } }
In this case, we’re only overriding onChange
to see all state changes that occur.
Note:
onChange
works the same way for bothBloc
andCubit
instances.
Next, let’s replace the contents of main.dart
with:
import 'package:bloc/bloc.dart'; import 'package:flutter/material.dart'; import 'app.dart'; import 'counter_observer.dart'; void main() { Bloc.observer = CounterObserver(); runApp(const CounterApp()); } Copy to clipboardErrorCopied
We’re initializing the CounterObserver
we just created and calling runApp
with the CounterApp
widget which we’ll look at next.
CounterApp
will be a MaterialApp
and is specifying the home
as CounterPage
.
import 'package:flutter/material.dart'; import 'counter/counter.dart'; /// {@template counter_app} /// A [MaterialApp] which sets the `home` to [CounterPage]. /// {@endtemplate} class CounterApp extends MaterialApp { /// {@macro counter_app} const CounterApp({Key key}) : super(key: key, home: const CounterPage()); }
Note: We are extending
MaterialApp
becauseCounterApp
is aMaterialApp
. In most cases, we’re going to be creatingStatelessWidget
orStatefulWidget
instances and composing widgets inbuild
but in this case there are no widgets to compose so it’s simpler to just extendMaterialApp
.
Here is end for part 1. Try to practice and I will continue in part 2 soon. See you later <3 <3 <3
You need to login in order to like this post: click here
YOU MIGHT ALSO LIKE