Рубрики
Flutter

Как использовать Flutter Provider для управления состоянием приложения

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 вы можете создавать приложения с чистым кодом, который легко понимать и поддерживать.