Provider State Management Flutter: provider Package Flutter Guide

Haris Bin Nasir Avatar

·

·

In this tutorial, we’ll explore the process of implementing state management in Flutter using the Provider package. This approach helps you maintain the state of your Flutter applications efficiently, making your code more scalable and easier to maintain.

If you prefer watching a video tutorial here is a link to that.

Introduction to Provider in Flutter

Provider is a popular state management solution for Flutter, offering a simple and flexible way to handle the state of your app. It allows widgets to listen to and react to changes in the app’s state, enabling dynamic updates without the need for cumbersome state management techniques.

Setting Up the Flutter Project

Before we dive into the implementation, let’s set up our Flutter project and install the necessary dependencies. These initial steps ensure that your environment is ready for development.

Project Setup and Dependencies

First, create a new Flutter project and add the Provider package to your pubspec.yaml file. This is essential for integrating state management into your app.

provider:

The provider package in Flutter is a robust solution for managing state across your application. It allows for a clean separation of logic and UI, making your app more maintainable and scalable. To get the dependency click here.

dependencies:
  flutter:
    sdk: flutter
  provider: ^6.0.0

Run flutter pub get to install the dependencies.

flutter pub get

Implementing State Management with Provider

Now, let’s start implementing the state management solution for our sample e-commerce app. This section will guide you through the process of integrating the Provider into your Flutter application.

Main Application Setup

In the main.dart file, we set up the main structure of our app and initialize the CartProvider, which will manage the state of the shopping cart.

Setting Up the Main Application:

Here, we begin by importing the necessary packages and setting up the basic structure of our Flutter application.

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:provider_state_management_tutorial/providers/cart_provider.dart';

import 'pages/cart_page.dart';
import 'pages/products_page.dart';

Initializing the Provider:

In this part, we initialize the Provider, ensuring that our state management solution is integrated into the app’s lifecycle.

void main() {
  runApp(
    ChangeNotifierProvider(
      create: (context) => CartProvider(),
      child: const MyApp(),
    ),
  );
}

Creating the MyApp Class:

Here, we define the MyApp class, setting up the routes and the basic navigation structure for the application.

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      initialRoute: "/products",
      routes: {
        "/products": (context) => ProductsPage(),
        "/cart": (context) => CartPage(),
      },
    );
  }
}

Creating the Product Model

Next, we’ll create a simple Product model to represent the items in our app. This model will contain information such as the product’s ID, name, price, and color.

Defining the Product Model:

This code snippet shows how to define the Product model, which is a blueprint for the products in our application.

import 'package:flutter/material.dart';

class Product {
  final int id;
  final String name;
  final double price;
  final Color color;

  Product({
    required this.id,
    required this.name,
    required this.price,
    required this.color,
  });
}

Creating a List of Products:

Here, we create a list of products that will be displayed in the app. Each product has a unique ID, name, price, and color.

final List<Product> PRODUCTS = [
  Product(
    id: 0,
    name: 'Laptop',
    price: 999.99,
    color: Colors.amber,
  ),
  Product(
    id: 1,
    name: 'Smartphone',
    price: 699.99,
    color: Colors.red,
  ),
  Product(
    id: 2,
    name: 'Wireless Earbuds',
    price: 129.99,
    color: Colors.green,
  ),
  Product(
    id: 3,
    name: 'Smartwatch',
    price: 199.99,
    color: Colors.blue,
  ),
  Product(
    id: 4,
    name: 'Gaming Console',
    price: 499.99,
    color: Colors.pink,
  ),
  Product(
    id: 5,
    name: '4K TV',
    price: 799.99,
    color: Colors.purple,
  ),
  Product(
    id: 6,
    name: 'Desktop Computer',
    price: 1299.99,
    color: Colors.teal,
  ),
  Product(
    id: 7,
    name: 'Bluetooth Speaker',
    price: 79.99,
    color: Colors.indigo,
  ),
  Product(
    id: 8,
    name: 'Camera Drone',
    price: 299.99,
    color: Colors.lime,
  ),
  Product(
    id: 9,
    name: 'Fitness Tracker',
    price: 129.99,
    color: Colors.cyan,
  ),
];

Creating the Cart Provider

The CartProvider is a ChangeNotifier class that will manage the state of the shopping cart. This section covers how to create the provider and implement the necessary functionalities.

Defining the CartProvider Class:

We start by defining the CartProvider class, which will handle the state of the cart in our application.

import 'package:flutter/material.dart';
import '../consts.dart';

class CartProvider extends ChangeNotifier {
  final List<Product> _items = [];

Adding and Removing Items from the Cart:

This code snippet shows how to add and remove items from the cart, updating the state of the application as changes occur.

List<Product> get items => _items;

void add(Product item) {
  _items.add(item);
  notifyListeners();
}

void remove(Product item) {
  _items.remove(item);
  notifyListeners();
}

Calculating the Total Cost of Items:

Finally, we implement a method to calculate the total cost of the items in the cart, ensuring that this information is available whenever needed.

double getCartTotal() {
  return _items.fold(0, (previousValue, item) => previousValue + item.price);
}

Building the Products Page

The ProductsPage displays a list of available products. Users can add products to their cart by selecting the corresponding checkbox. The state of the cart is managed by the CartProvider.

Setting Up the Products Page:

In this section, we set up the basic structure of the ProductsPage, which will display the products available in the app.

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../providers/cart_provider.dart';
import '../consts.dart';

class ProductsPage extends StatelessWidget {
  const ProductsPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: _appBar(context),
      body: _buildUI(context),
    );
  }
}

Creating the AppBar:

We create the app bar for the ProductsPage, which includes navigation to the cart page.

PreferredSizeWidget _appBar(BuildContext context) {
  return AppBar(
    title: const Text("Products"),
    actions: [
      IconButton(
        onPressed: () {
          Navigator.pushNamed(context, "/cart");
        },
        icon: const Icon(Icons.shopping_cart),
      ),
    ],
  );
}

Building the Product List UI:

Here, we build the user interface for the product list, allowing users to interact with the products and add them to their cart.

Widget _buildUI(BuildContext context) {
  CartProvider cartProvider = Provider.of<CartProvider>(context);
  return ListView.builder(
    itemCount: PRODUCTS.length,
    itemBuilder: (context, index) {
      Product product = PRODUCTS[index];
      return ListTile(
        leading: Container(
          height: 25,
          width: 25,
          color: product.color,
        ),
        title: Text(product.name),
        trailing: Checkbox(
          value: cartProvider.items.contains(product),
          onChanged: (value) {
            if (value == true) {
              cartProvider.add(product);
            } else {
              cartProvider.remove(product);
            }
          },
        ),
      );
    },
  );
}

Building the Cart Page

The CartPage displays the items that the user has added to the cart. It also shows the total cost of the items and allows users to remove items from the cart.

Setting Up the Cart Page:

We begin by setting up the basic structure of the CartPage, which will display the items in the user’s cart.

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../providers/cart_provider.dart';

class CartPage extends StatelessWidget {
  const CartPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: _appBar(),
      body: _buildUI(),
    );
  }
}

Creating the AppBar:

This code snippet shows how to create the app bar for the CartPage, providing a consistent user interface across the app.

PreferredSizeWidget _appBar() {
  return AppBar(
    title: const Text("Cart"),
  );
}

Building the Cart UI:

Finally, we build the user interface for the cart, allowing users to view and manage the items they have added.

Widget _buildUI() {
  return Consumer<CartProvider>(
    builder: (context, provider, _) {
      return Column(
        children: [
          Expanded(
            child: ListView.builder(
              itemCount: provider.items.length,
              itemBuilder: (context, index) {
                Product product = provider.items[index];
                return ListTile(
                  title: Text(product.name),
                  onLongPress: () {
                    provider.remove(product);
                  },
                );
              },
            ),
          ),
          Text("Cart Total: \$${provider.getCartTotal()}")
        ],
      );
    },
  );
}

Get Source Code for free:

Conclusion

By following this guide, you’ve learned how to implement state management in a Flutter application using the Provider package. This method allows for a clean separation of concerns and makes your app more maintainable as it scales. The ChangeNotifier class provided by Flutter is a powerful tool for managing state in a predictable and efficient manner.

Whether you’re building a simple app or a complex one, mastering state management with Provider will help you create more responsive and user-friendly Flutter applications.

Happy Coding…!!!

Leave a Reply

Your email address will not be published. Required fields are marked *