What is a Provider? 🤔
Imagine you're at a buffet (yum!). You have a plate (your app screen) and a variety of dishes (data) to choose from. Now, you don't cook a new dish every time you want to eat (that's just exhausting!). Instead, you go to the buffet (Provider) and pick what you need. Easy peasy! Provider in Flutter is like this buffet. It's a central spot where your app's data is stored, ready to be used by different widgets.
Let's use a real-life analogy to explain this concept:
Imagine you're building a to-do list app. In this app, you have a list of tasks that you want to display on different screens, like the home screen and a detail screen for each task. You also want to be able to add, edit, or delete tasks from any screen.
Now, think of the Provider as a bucket. This bucket contains your list of tasks. Every time you make a change to this bucket, it automatically updates all the screens in your app that are interested in the task list.
Why Use Provider? 🚀
Using setState everywhere in Flutter can be like using a hammer for every problem - not ideal! It can lead to performance issues and make your app as slow as a sloth on a lazy day. Provider to the rescue! It separates your app's brain (logic) from its beauty (UI), keeping your code clean, organized, and as pretty as a picture.
Using Provider in a Todo/Task App
1. Import Dependency
dependencies:
provider:
2. Create a Model Class for Our Task
class Task {
final String title;
final String description;
Task({required this.title, required this.description});
}
3. Creating a Provider
You create a provider by defining a class that holds the data you want to share, in this case, your task list.
class TaskProvider extends ChangeNotifier {
List<Task> _tasks = [];
// Methods to add, edit, or delete tasks go here
// Getter to access the task list
List<Task> get tasks => _tasks;
// Method to add a new task
void addTask(Task newTask) {
_tasks.add(newTask);
notifyListeners(); // Notify listeners to rebuild widgets
}
}
4. Initializing the Provider
You create an instance of your provider class and make it available to your app. This is typically done at the root of your app using a ChangeNotifierProvider
.
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => TaskProvider(),
child: MyApp(),
),
);
}
5. Accessing Data
Now, any widget in your app can access the task list from the provider. For example, your home screen can display the list of tasks like this:
final tasks = Provider.of<TaskProvider>(context).tasks;
6. Updating Data
When you add, edit, or delete a task, you do it through the provider. The provider updates its internal data and automatically notifies all the widgets that are listening to it. For example, when you add a new task:
final taskProvider = Provider.of<TaskProvider>(context);
taskProvider.addTask(newTask);
7. Widget Rebuild
When the provider notifies that the data has changed, widgets that depend on that data will automatically rebuild to reflect the updated information. So, your home screen will refresh to display the new task you added.
ListView.builder(
itemCount: taskProvider.tasks.length,
itemBuilder: (context, index) {
final task = taskProvider.tasks[index];
return ListTile(
title: Text(task.title),
subtitle: Text(task.description),
);
},
),
That's it you aced this!!! It was that simple
Conclusion 🌈
So, next time you dive into a Flutter project, remember the Provider - your data management superhero! With Provider, managing state is as smooth as spreading butter on warm toast. Happy Fluttering 🎉✨🚀