Menggunakan Multiple Provider

Flutter memungkinkan kita untuk meregistrasikan lebih dari satu provider. Implementasi multiple provider digunakan untuk menampilkan data pada shopping cart.

App bar akan menampilkan shopping cart, setiap produk ditambahkan ke shopping cart, icon shopping cart akan diupdate dan menampilkan badge jumlah item didalamnya.

Pertama, kita perlu buat dahulu class provider yang akan menangani data cart. Buat file baru silakan beri nama, pada tutorial digunakan cart_provider.dart

//cart_provider.dart

import 'package:flutter/foundation.dart';

class CartItem {
  final String id;
  final String title;
  final double price;
  final int qty;

  CartItem({
    @required this.id,
    @required this.title,
    @required this.price,
    @required this.qty,
  });
}

class Cart with ChangeNotifier {
  Map<String, CartItem> _cartItem = {};

  Map<String, CartItem> get cartItem {
    return {..._cartItem};
  }

  int get totalItem {
    return _cartItem.length;
  }

  double get totalAmount {
    var total = 0.0;
    _cartItem.forEach((key, value) {
      total += value.price * value.qty;
    });
    return total;
  }

  void addItem(String pid, String title, double price) {
    if (_cartItem.containsKey(pid)) {
      _cartItem.update(
          pid,
          (ccart) => CartItem(
              id: ccart.id,
              title: ccart.title,
              price: ccart.price,
              qty: ccart.qty + 1));
    } else {
      _cartItem.putIfAbsent(
          pid,
          () => CartItem(
              id: DateTime.now().toString(),
              title: title,
              price: price,
              qty: 1));
    }
    notifyListeners();
  }
}

Berikutnya kita buat widget untuk menampilkan isi cart. Pada tutorial digunakan nama cart_scr.dart

//cart_scr.dart

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

import '../models/cart_provider.dart';
import './cart_content.dart';

class CartSccr extends StatelessWidget {
  static const routeNm = '/cart';

  @override
  Widget build(BuildContext context) {
    final cartCnt = Provider.of<Cart>(context);
    return Scaffold(
      appBar: AppBar(
        title: Text('Your Cart'),
      ),
      body: Column(
        children: <Widget>[
          Card(
            margin: EdgeInsets.all(8),
            child: Padding(
              padding: const EdgeInsets.all(8.0),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: <Widget>[
                  Text(
                    'Total',
                    style: TextStyle(
                      fontSize: 18,
                    ),
                  ),
                  Spacer(),
                  Chip(
                    label: Text(
                      '\$${cartCnt.totalAmount}',
                      style: TextStyle(color: Colors.white),
                    ),
                    backgroundColor: Theme.of(context).primaryColor,
                  ),
                  FlatButton(
                    onPressed: null,
                    child: Text('Order Now'),
                    textColor: Theme.of(context).primaryColor,
                  ),
                ],
              ),
            ),
          ),
          SizedBox(height: 10),
          Expanded(
            child: ListView.builder(
              itemCount: cartCnt.cartItem.length,
              itemBuilder: (ctx, i) => CartContent(
                  cartCnt.cartItem.values.toList()[i].id,
                  cartCnt.cartItem.values.toList()[i].title,
                  cartCnt.cartItem.values.toList()[i].price,
                  cartCnt.cartItem.values.toList()[i].qty),
            ),
          ),
        ],
      ),
    );
  }
}

Jangan lupa, registrasi provider untuk manage data cart pada main.dart

//main.dart

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

import './widgets/product_view_scr.dart';
import './widgets/product_detail_scr.dart';
import './models/products_provider.dart';
import 'models/cart_provider.dart';
import './widgets/cart_scr.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(
          create: (ctx) => ProductsProvider(),
        ),
        ChangeNotifierProvider(
          create: (ctx) => Cart(),
        )
      ],
      child: MaterialApp(
        title: 'AZShop',
        theme: ThemeData(
          primarySwatch: Colors.red,
          accentColor: Colors.red[300],
          visualDensity: VisualDensity.adaptivePlatformDensity,
          fontFamily: 'Lato',
        ),
        home: ProductViewScr(),
        routes: {
          ProductDetailScr.routeNm: (ctx) => ProductDetailScr(),
          CartSccr.routeNm: (ctx) => CartSccr(),
        },
      ),
    );
  }
}

file product_view_scr.dart

//product_view_scr.dart

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

import '../models/products_provider.dart';
import './product_item.dart';
import '../models/cart_provider.dart';
import './badge.dart';
import './cart_scr.dart';

enum FilterOpt { Favorite, All }

class ProductViewScr extends StatefulWidget {
  @override
  _ProductViewScrState createState() => _ProductViewScrState();
}

class _ProductViewScrState extends State<ProductViewScr> {
  bool _showFav = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('AZShop'),
        actions: <Widget>[
          PopupMenuButton(
            onSelected: (FilterOpt selected) {
              setState(() {
                if (selected == FilterOpt.Favorite) {
                  _showFav = true;
                } else {
                  _showFav = false;
                }
              });
            },
            itemBuilder: (_) => [
              PopupMenuItem(
                child: Text('Favorite'),
                value: FilterOpt.Favorite,
              ),
              PopupMenuItem(
                child: Text('Show All'),
                value: FilterOpt.All,
              ),
            ],
            icon: Icon(Icons.more_vert),
          ),
          Consumer<Cart>(
            builder: (_, cartData, ch) => Badge(
              child: ch,
              value: cartData.totalItem.toString(),
            ),
            child: IconButton(
              icon: Icon(Icons.shopping_cart),
              onPressed: () {
                Navigator.of(context).pushNamed(CartSccr.routeNm);
              },
            ),
          ),
        ],
      ),
      body: ProductsGrid(_showFav),
    );
  }
}

class ProductsGrid extends StatelessWidget {
  final bool isFav;

  ProductsGrid(this.isFav);

  @override
  Widget build(BuildContext context) {
    final productsData = Provider.of<ProductsProvider>(context);
    final products =
        isFav ? productsData.productsFav : productsData.productsList;
    return GridView.builder(
        padding: const EdgeInsets.all(8),
        itemCount: products.length,
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 2,
            childAspectRatio: 3 / 2,
            crossAxisSpacing: 8,
            mainAxisSpacing: 8),
        itemBuilder: (ctx, i) => ChangeNotifierProvider.value(
            //create: (ctx) => products[i],
            value: products[i],
            child: ProductItem()));
  }
}

Terakhir adalah file cart_content.dart, file widget untuk menampilkan item dari cart

//cart_content.dart

import 'package:flutter/material.dart';

class CartContent extends StatelessWidget {
  final String id;
  final String title;
  final int qty;
  final double prc;

  CartContent(this.id, this.title, this.prc, this.qty);

  @override
  Widget build(BuildContext context) {
    return Card(
      margin: EdgeInsets.symmetric(horizontal: 5, vertical: 7),
      child: Padding(
        padding: EdgeInsets.all(8),
        child: ListTile(
          leading: CircleAvatar(child: FittedBox(child: Text('\$$prc'))),
          title: Text(title),
          subtitle: Text('Total: \$${prc * qty}'),
          trailing: Text('\$$qty x'),
        ),
      ),
    );
  }
}

Sharing is caring:

Leave a Comment