Skip to content

Instantly share code, notes, and snippets.

@prof3ssorSt3v3
Created March 27, 2025 20:28
Show Gist options
  • Save prof3ssorSt3v3/4aab95459ff58a00957ca9fb227adbc9 to your computer and use it in GitHub Desktop.
Save prof3ssorSt3v3/4aab95459ff58a00957ca9fb227adbc9 to your computer and use it in GitHub Desktop.
Flutter example of a change notifier
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
//add provider: to the dependencies in pubspec.yaml
//update your formatter in analysis_options.yaml
// The provider file to be imported in files that need it
class NameProvider extends ChangeNotifier {
List<String> _names = ['Bob', 'Louise'];
//similar in concept to a State variable but it will be
//used and managed from inside other widgets in the tree
List<String> get names => _names;
void addName(String name) {
//be sure to validate the new data
_names.add(name);
//Call notifyListeners() whenever the value changes
notifyListeners();
}
void removeName(String name) {
_names.remove(name);
//Call notifyListeners() when the value changes
notifyListeners();
}
}
//main.dart import the provider package AND our custom provider
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => NameProvider(),
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: HomePage(),
);
}
}
// the page using the Provider through a consumer
//import both the provider package and the custom provider files
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final TextEditingController _nameController =
TextEditingController();
@override
void dispose() {
_nameController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final nameListProvider = Provider.of<NameProvider>(context);
return Scaffold(
appBar: AppBar(title: Text('Provider Example')),
body: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: <Widget>[
Expanded(
child: TextField(
controller: _nameController,
decoration: InputDecoration(
labelText: 'Enter Name',
),
),
),
SizedBox(width: 8),
ElevatedButton(
onPressed: () {
final name = _nameController.text.trim();
if (name.isNotEmpty) {
nameListProvider.addName(name);
//Provider.of<NameProvider>(context)
_nameController.clear();
}
},
child: Text('Add'),
),
],
),
),
Expanded(
child: Consumer<NameProvider>(
builder: (context, provider, child) {
//provider == Provider.of<NameProvider>(context)
return ListView.builder(
itemCount: provider.names.length,
itemBuilder: (context, index) {
final name = provider.names[index];
return ListTile(
title: Text(name),
trailing: OutlinedButton.icon(
icon: Icon(Icons.delete),
label: child!,
onPressed: () {
provider.removeName(name);
},
),
);
},
);
},
child: Text('Delete'),
//becomes the child param in builder: (context, provider, child)
),
),
],
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment