Flutter Provider — это библиотека для управления состоянием приложения в Flutter. Она помогает легко передавать данные между виджетами и управлять ими, минуя необходимость использования стейтфул-виджетов. В этой статье мы рассмотрим, как использовать Flutter Provider для управления состоянием приложения.
Шаг 1: Установка Flutter Provider
Первым шагом является установка Flutter Provider. Для этого добавьте следующую строку в ваш файл pubspec.yaml
:
dependencies:
provider: ^6.0.1
После этого запустите команду flutter packages get
для установки Flutter Provider.
Шаг 2: Создание модели данных
Во втором шаге мы создадим модель данных для нашего приложения. В качестве примера, мы будем использовать список задач. Создайте новый файл task_model.dart
и добавьте следующий код:
class TaskModel {
final int id;
final String title;
final bool isDone;
TaskModel({required this.id, required this.title, this.isDone = false});
}
Здесь мы создали простую модель TaskModel
, которая содержит идентификатор, заголовок и флаг, указывающий, выполнена ли задача.
Шаг 3: Создание класса управления состоянием
Для управления состоянием приложения мы создадим класс TaskProvider
, который будет содержать список задач и необходимые методы для управления ими. Создайте новый файл task_provider.dart
и добавьте следующий код:
import 'package:flutter/foundation.dart';
import 'package:provider/provider.dart';
import 'task_model.dart';
class TaskProvider extends ChangeNotifier {
List<TaskModel> _tasks = [
TaskModel(id: 1, title: 'Купить молоко'),
TaskModel(id: 2, title: 'Сходить в банк'),
TaskModel(id: 3, title: 'Посетить спортзал'),
];
List<TaskModel> get tasks => _tasks;
void addTask(String title) {
final newTask = TaskModel(id: _tasks.length + 1, title: title);
_tasks.add(newTask);
notifyListeners();
}
void toggleTask(int id) {
final taskIndex = _tasks.indexWhere((task) => task.id == id);
_tasks[taskIndex].isDone = !_tasks[taskIndex].isDone;
notifyListeners();
}
void deleteTask(int id) {
_tasks.removeWhere((task) => task.id == id);
notifyListeners();
}
}
Здесь мы создали класс TaskProvider
, который содержит список задач _tasks
и три метода для добавления, изменения и удаления задач. Обратите внимание на использование метода notifyListeners()
. Он уведомляет все подписанные виджеты о необходимости обновления состояния.
Теперь мы объявим наш TaskProvider
в виджете, чтобы использовать его для управления состоянием приложения. Для этого создадим корневой виджет MyApp
, в котором мы обернем весь приложение в ChangeNotifierProvider
:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'task_provider.dart';
import 'task_screen.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => TaskProvider(),
child: MaterialApp(
title: 'Flutter Provider Demo',
home: TaskScreen(),
),
);
}
}
Здесь мы использовали ChangeNotifierProvider
, чтобы создать экземпляр TaskProvider
и передать его в качестве значения create
. Затем мы обернули наше приложение в MaterialApp
и установили TaskScreen
в качестве домашнего экрана.
Шаг 5: Использование Provider в виджетах
Теперь мы можем использовать TaskProvider
в наших виджетах, чтобы управлять состоянием приложения. Для этого мы используем Provider.of<TaskProvider>(context)
для получения экземпляра TaskProvider
.
Например, в TaskScreen
мы можем использовать Consumer<TaskProvider>
для перерисовки только необходимых частей экрана при изменении состояния TaskProvider
:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'task_model.dart';
import 'task_provider.dart';
class TaskScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Мои задачи'),
),
body: Consumer<TaskProvider>(
builder: (context, taskProvider, child) => ListView.builder(
itemCount: taskProvider.tasks.length,
itemBuilder: (context, index) {
final task = taskProvider.tasks[index];
return CheckboxListTile(
title: Text(task.title),
value: task.isDone,
onChanged: (value) {
taskProvider.toggleTask(task.id);
},
);
},
),
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
final title = await _showTaskDialog(context);
if (title != null && title.isNotEmpty) {
Provider.of<TaskProvider>(context, listen: false).addTask(title);
}
},
tooltip: 'Добавить задачу',
child: Icon(Icons.add),
),
);
}
Future<String?> _showTaskDialog(BuildContext context) {
final controller = TextEditingController();
return showDialog<String>(
context: context,
builder: (context) => AlertDialog(
title: Text('Добавить задачу'),
content: TextField(
controller: controller,
decoration: InputDecoration(hintText: 'Введите задачу'),
),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: Text('Отмена'),
),
TextButton(
onPressed: () => Navigator.pop(context, controller.text),
child: Text('Добавить'),
),
Шаг 6: Изменение состояния Provider
Теперь мы можем обновлять состояние приложения, используя методы TaskProvider
. Например, мы можем использовать addTask
для добавления новой задачи:
Provider.of<TaskProvider>(context, listen: false).addTask(title);
Или мы можем использовать toggleTask
для переключения состояния задачи:
taskProvider.toggleTask(task.id);
Заключение
В этой статье мы рассмотрели, как использовать Flutter Provider для управления состоянием приложения. Мы создали TaskProvider
, который наследуется от ChangeNotifier
, и используем его для хранения списка задач. Затем мы создали виджет TaskScreen
, который использует Consumer<TaskProvider>
для обновления состояния при изменении списка задач.
Flutter Provider является мощным инструментом для управления состоянием в Flutter-приложениях. Он позволяет создавать экземпляры классов Provider, которые могут использоваться для хранения и обновления состояния приложения в любом месте приложения. С помощью Provider вы можете создавать приложения с чистым кодом, который легко понимать и поддерживать.