Skip to content

Instantly share code, notes, and snippets.

@chonghorizons
Last active December 4, 2021 02:06
Show Gist options
  • Save chonghorizons/90da115645caf06ffe10dc8ab170f347 to your computer and use it in GitHub Desktop.
Save chonghorizons/90da115645caf06ffe10dc8ab170f347 to your computer and use it in GitHub Desktop.
// This code is distributed under the MIT License.
// Copyright (c) 2018 Felix Angelov.
// Ported to dartpad.dev 2021 by Howard "horizons" Chong.
// You can find the original at https://github.com/felangel/bloc.
// Specifically, see https://github.com/felangel/bloc/tree/master/examples/flutter_counter
//
// The tutorial/guide at https://bloclibrary.dev/#/fluttercountertutorial describes this code.
// Linkback to DartPad: https://dartpad.dev/90da115645caf06ffe10dc8ab170f347
//
// ===== TROUBLESHOOTING INSTRUCTIONS =====
// This should auto-run. If it does not auto-run, then do the following:
// 1. Go to https://dartpad.dev/90da115645caf06ffe10dc8ab170f347 (you may alrady be there)
// 2. Hit the "Run" button.
// 3. Wait. It may take up to 2 minutes if you are on a slow connection.
// 4. Once it loads, it should look like this: https://imgur.com/gallery/zRjmEBq
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter/material.dart';
void main() {
BlocOverrides.runZoned(
() => runApp(const CounterApp()),
blocObserver: AppBlocObserver(),
);
}
class CounterApp extends MaterialApp {
/// {@macro counter_app}
const CounterApp({Key? key}) : super(key: key, home: const CounterPage());
}
/// {@template counter_cubit}
/// A [Cubit] which manages an [int] as its state.
/// {@endtemplate}
class CounterCubit extends Cubit<int> {
/// {@macro counter_cubit}
CounterCubit() : super(0);
/// Add 1 to the current state.
void increment() => emit(state + 1);
/// Subtract 1 from the current state.
void decrement() => emit(state - 1);
}
/// {@template counter_page}
/// A [StatelessWidget] which is responsible for providing a
/// [CounterCubit] instance to the [CounterView].
/// {@endtemplate}
class CounterPage extends StatelessWidget {
/// {@macro counter_page}
const CounterPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (_) => CounterCubit(),
child: CounterView(),
);
}
}
/// {@template counter_view}
/// A [StatelessWidget] which reacts to the provided
/// [CounterCubit] state and notifies it in response to user input.
/// {@endtemplate}
class CounterView extends StatelessWidget {
@override
Widget build(BuildContext context) {
final textTheme = Theme.of(context).textTheme;
return Scaffold(
appBar: AppBar(title: const Text('Counter')),
body: Center(
child: BlocBuilder<CounterCubit, int>(
builder: (context, state) {
return Text('$state', style: textTheme.headline2);
},
),
),
floatingActionButton: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
FloatingActionButton(
key: const Key('counterView_increment_floatingActionButton'),
child: const Icon(Icons.add),
onPressed: () => context.read<CounterCubit>().increment(),
),
const SizedBox(height: 8),
FloatingActionButton(
key: const Key('counterView_decrement_floatingActionButton'),
child: const Icon(Icons.remove),
onPressed: () => context.read<CounterCubit>().decrement(),
),
],
),
);
}
}
/// =====
/// Custom [BlocObserver] that observes all bloc
/// and cubit state changes, sent to console.
/// NOTE: This is generic and works for all cubit and bloc
/// objects. The original example uses a CounterObserver see
class AppBlocObserver extends BlocObserver {
@override
void onChange(BlocBase bloc, Change change) {
super.onChange(bloc, change);
if (bloc is Cubit ) print('${bloc.runtimeType} $change');
}
@override
void onTransition(Bloc bloc, Transition transition) {
super.onTransition(bloc, transition);
print('${bloc.runtimeType} $transition');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment