Flutter Exam Kit: Bloc & Provider Snippets
Clean architecture in seconds: data · domain · presentation, Bloc or Provider.
Clean-architecture Flutter templates. In any .dart file, type ex and pick a snippet, or type the full prefix and press Tab.
How the snippets work
- Type a prefix, e.g.
exbloc, and press Tab.
- The first highlighted word is the feature name (default
Item). Type your name, e.g. Product, and every class name changes with it: ProductBloc, FetchProducts, ProductLoaded, products…
- Press Tab to jump to the next field. Press Esc when you're done.
Use a singular, PascalCase name: Product, Book, OrderItem.
Create a whole feature in one go
Ctrl+Shift+P → Flutter Exam: Create Feature (all layers)
You answer a few questions: the name, the kind of feature, API or local list, the base URL, and whether to replace main.dart. It then writes every file with the correct imports.
| Kind of feature |
Files it creates |
| Bloc: list + CRUD |
entity, abstract repo, model (API), repo impl, events, states, bloc, list page, detail page |
| Provider: list + CRUD |
entity, abstract repo, model (API), repo impl, notifier (ChangeNotifier), list page with Consumer, detail page |
| Bloc: simple state |
events, state (one class + copyWith), bloc, page |
| Provider: simple state |
notifier, page with Consumer + buttons |
Provider list + CRUD, for example:
lib/features/product/
├── data/
│ ├── models/product_model.dart fromJson / toJson (API only)
│ └── repositories/product_repository_impl.dart http or local list
├── domain/
│ ├── entities/product.dart plain class
│ └── repositories/product_repository.dart abstract contract
└── presentation/
├── statemanagement/provider/product_provider.dart ChangeNotifier (the notifier)
└── ui/product_page.dart, product_detail_page.dart Consumer + context.read
Then it offers to run flutter pub add flutter_bloc http (or provider) for you.
No time to make files? One snippet = whole feature
Type exfeaturepv (Provider) or exfeaturebloc (Bloc) in an empty main.dart. You get every layer plus main() in one file, ready to run. Variants: exfeaturepvl / exfeatureblocl (local list, no API) and exfeaturepvs / exfeatureblocs (simple counter-style state).
To see this page again: Ctrl+Shift+P → Flutter Exam: Open Cheat Sheet.
Memory hooks
| Hook |
Meaning |
| PSSG (Bloc) |
Provide in main.dart → Show with BlocBuilder → Send with context.read<XBloc>().add(...) → Go with Navigator.push |
| N-P-C (Provider) |
Notifier (ChangeNotifier + notifyListeners()) → Provider (ChangeNotifierProvider) → Consumer (Consumer<X>) |
| INDEX → PAGES → SELECT → SHOW |
Bottom navbar: int index, List pages, setState, body: pages[index] |
| L-E-L-S |
BlocBuilder order: Loading → Error → Loaded → SizedBox |
pubspec.yaml
In pubspec.yaml under dependencies:, type exdeps to insert flutter_bloc, provider and http.
All prefixes
Whole feature in ONE snippet (paste into main.dart and run)
| Prefix |
What you get |
exfeaturebloc |
WHOLE Bloc feature in one file (API): entity, model, repo, bloc, pages, main |
exfeatureblocl |
WHOLE Bloc feature in one file (local list, no API) |
exfeaturepv |
WHOLE Provider feature in one file (API): entity, model, repo, notifier, pages, main |
exfeaturepvl |
WHOLE Provider feature in one file (local list, no API) |
exfeatureblocs |
WHOLE simple Bloc feature in one file (counter style, no API) |
exfeaturepvs |
WHOLE simple Provider feature in one file (counter style, no API) |
exstructure |
Folder structure trees (Bloc, Provider, simple) as a comment |
Simple state (counter / toggle / stepper, no API)
| Prefix |
What you get |
expvsimple |
Simple Provider notifier (counter / toggle style, no API) |
expvsimplepage |
Page for a simple Provider: Consumer + buttons |
expvsimplemain |
main.dart for a simple Provider feature |
exsimpleevents |
Simple Bloc events (Increment / Decrement / Reset) |
exsimplestate |
Simple Bloc state: one class with copyWith |
exsimplebloc |
Simple Bloc (no API) using copyWith |
exsimplepage |
Page for a simple Bloc: BlocBuilder + buttons |
exsimplemain |
main.dart for a simple Bloc feature |
Data + Domain
| Prefix |
What you get |
exentity |
Domain entity class |
exmodel |
Data model with fromJson / toJson / toEntity |
exrepo |
Domain abstract repository (contract) |
eximpl |
Data repository implementation with http CRUD |
exlocal |
Repository implementation with a local list (no API) |
exhttp |
All 5 http calls (GET / POST / PUT / PATCH / DELETE) |
Bloc
| Prefix |
What you get |
exevents |
Bloc events (Fetch / Add / Update / Delete) |
exstates |
Bloc states (Initial / Loading / Loaded / Error) |
exbloc |
Bloc with full CRUD handlers |
exmain |
main.dart with MultiBlocProvider (blocs above MaterialApp) |
exbuilder |
BlocBuilder with the Loading / Error / Loaded ladder |
exread |
Send an event to a bloc: context.read().add(...) |
exblocprovider |
Single BlocProvider wrapping a widget |
exblocline |
One more BlocProvider line for MultiBlocProvider |
exblocvalue |
Push a page and pass the SAME bloc (BlocProvider.value) |
exlistener |
BlocListener: show a SnackBar on error |
exblocconsumer |
BlocConsumer = BlocListener + BlocBuilder |
exmultilistener |
MultiBlocListener |
exstatebloc |
Local-state bloc (no API): events + one state with copyWith + bloc |
excart |
Cart bloc: AddToCart / RemoveFromCart / ClearCart + count + total |
Provider
| Prefix |
What you get |
exnotifier |
Provider basic template: ChangeNotifier with notifyListeners |
expvcrud |
Provider (ChangeNotifier) with loading, error and CRUD |
expvmain |
main.dart with MultiProvider (providers above MaterialApp) |
expvpage |
Full CRUD page with Consumer (Provider version) |
expvconsumer |
Consumer (rebuilds only this part) |
expvread |
Call a provider method from a button: context.read |
expvwatch |
context.watch inside build (rebuilds whole build) |
expvselector |
Selector: rebuild only when one value changes (badge count) |
expvline |
One more ChangeNotifierProvider line for MultiProvider |
expvcart |
Cart with Provider: add / remove / clear + count + total |
Pages + Navigation
| Prefix |
What you get |
expage |
Full CRUD page with BlocBuilder, add/edit dialog, delete, detail link |
exdetail |
Detail page that receives data through the constructor |
exnav |
Navigation helpers: go / goReplace / back (write once) |
expush |
Navigator.push to a page |
expushdata |
Navigator.push and pass data through the constructor |
expushresult |
Push a page and wait for a value back |
expop |
Navigator.pop (go back) |
exreplace |
Navigator.pushReplacement (no way back) |
exroutes |
Named routes in MaterialApp + pushNamed |
exhome |
Home shell: Drawer + BottomNavigationBar (INDEX, PAGES, SELECT, SHOW) |
exbottomnav |
BottomNavigationBar only |
exdrawer |
Drawer with header and items |
exstateless |
StatelessWidget page with Scaffold |
exstateful |
StatefulWidget page with setState |
Tabs: DefaultTabController + TabBar
| Prefix |
What you get |
extabs |
TabBar + TabBarView |
extabpage |
Full page: DefaultTabController + TabBar (icon + text) + TabBarView with a list |
extabrow |
One Tab with icon and text side by side (Row) |
extabcontroller |
TabController in a StatefulWidget (switch tab from code) |
Ready-made screens
| Prefix |
What you get |
exlogin |
Login screen: email + password validation, show/hide, go to home |
exprofile |
Profile screen: avatar, name, email, info card, edit button |
exsplash |
Splash screen: logo, then go to home after 2 seconds |
expageview |
Onboarding: PageView with dots and Next / Get started |
Lists: ListView + ListTile
| Prefix |
What you get |
exlist |
ListView.builder with Card + ListTile |
exlistbuilder |
ListView.builder with plain ListTile (no Card) |
exlistseparated |
ListView.separated (Divider between rows) |
exliststatic |
ListView with fixed ListTiles (menu / settings / profile) |
exlistcolumn |
Header text + list in a Column (ListView inside Expanded) |
exlistbloc |
BlocBuilder that shows the Loaded list as ListTiles (+ delete) |
exlistpv |
Consumer that shows the Provider list as ListTiles (+ delete) |
extile |
ListTile: avatar, title, subtitle, arrow, onTap |
extileactions |
ListTile with Edit + Delete buttons on the right |
extilecheck |
CheckboxListTile (todo / task style) |
extileswitch |
SwitchListTile (settings style, inside a StatefulWidget) |
exexpansion |
ExpansionTile (tap a row to show more) |
Images: asset + network
| Prefix |
What you get |
eximageasset |
Image.asset: static image from the assets folder (+ pubspec steps) |
eximage |
Image from the internet |
eximagenet |
Image.network with loading spinner and error icon |
eximageround |
Rounded-corner image (ClipRRect) |
exavatarimg |
CircleAvatar with a network or asset picture |
eximagecard |
Product card: image on top, title, price |
eximagebg |
Background image behind content (DecorationImage) |
| Prefix |
What you get |
extextfield |
TextField with label, hint, icon and border |
expassword |
Password field with show / hide eye button |
exform |
Form with TextFormField validation |
exdropdown |
DropdownButton (select one option) |
exradio |
Radio buttons (RadioListTile group) |
excheckbox |
Checkbox with label (CheckboxListTile) |
exslider |
Slider (pick a number) |
exswitch |
Switch (on / off) |
exdatepicker |
Button that opens a date picker (showDatePicker) |
exsearch |
Search box that filters a list (inside a StatefulWidget) |
| Prefix |
What you get |
exbutton |
Full-width rounded button |
exbuttonsall |
Every button type (Elevated, Outlined, Text, Icon, with icon, FAB) |
exbuttons |
Two buttons side by side (Back / Next style) |
| Prefix |
What you get |
exappbar |
AppBar with leading, centered title, colors and actions |
exstack |
Stack + Positioned: text and a button on top of an image |
exexpanded |
Row with Expanded (share space by flex) |
exscroll |
SingleChildScrollView + Column (long forms, no overflow) |
exgrid |
GridView.builder (2 per row) |
exgridcount |
GridView.count: fixed category grid |
exchips |
Wrap of Chips (tags) |
exinkwell |
InkWell: make any widget tappable (ripple) |
exbox |
White rounded box (card look) |
exgradient |
Full-screen gradient background |
exrichtext |
Text with two styles in one line (Text.rich) |
exprogress |
Progress bars (linear with value + circular) |
exbadge |
Icon with a count badge |
exsteps |
Step indicator: circles joined by lines |
exswipe |
Dismissible: swipe a row to delete |
exhero |
Hero animation between two pages (same tag on both) |
exanimated |
AnimatedContainer that grows when tapped |
exfuture |
FutureBuilder: loading / error / data (without Bloc) |
Dialogs + messages
| Prefix |
What you get |
exdialog |
AlertDialog with TextField (add / edit) |
exconfirm |
Confirm dialog (Yes / No) before delete |
exbottomsheet |
showModalBottomSheet with options |
exsnack |
Show a SnackBar message |
exsnackaction |
SnackBar with an UNDO action |
Help
| Prefix |
What you get |
excheat |
Cheat sheet comment: PSSG, N-P-C, file order, folders |
| |