Local State vs Global State

Global State

Menggunakan contoh kasus dari file product_item.dart, jika button favorite pada contoh hanya untuk mengubah tampilan pada level widget, kita dapat menggunakan stateful widget untuk melakukannya. Tidak diperlukan provider untuk mengelola state dalam scope yang lebih luas.

Namun, pada kasus ini, button favorite tidak hanya merubah tampillan icon saja, namun informasi dari widget digunakan akan digunakan untuk melakukan filtering dalam menampilkan favorite product saja atau all product. Oleh karena itu, kita gunakan pendekatan Provider.

Local State

Pada file product_view_scr.dart, kita tambahkan button pada app bar untuk menampilkan panel untuk memilih filter untuk menampilkan product. Karena data favorite atau all product hanya akan berlaku pada screen atau page ini, maka pendekatan yang dilakukan adalah menggunakan stateful widget.

Perintah setState harus dipanggil saat user memilih filter favorite atau all product. Saat menu dipilih, variable _showFav akan diset, yang kemudian data ini akan digunakan saat memanggil widget ProductsGrid.

...
...
PopupMenuButton(
  onSelected: (FilterOpt selected) {
    setState(() {
      if (selected == FilterOpt.Favorite) {
        _showFav = true;
      } else {
        _showFav = false;
      }
    });
  },
...
...
...

Pada class ProductGrid, kita tambahkan constructor, yang isinya akan melakukan inisialisasi variable isFav. Dimana nilai isFav akan digunakan untuk memilih, method productsFav atau productList.

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(
//product_view_src.dart

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

import '../models/products_provider.dart';
import './product_item.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),
          )
        ],
      ),
      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()));
  }
}

Pada provider kita tambahkan method baru untuk mengambil list product favorite.

List<Product> get productsFav {
  return _products.where((element) => element.isFav).toList();
}
import 'package:flutter/material.dart';
import './product.dart';

class ProductsProvider with ChangeNotifier {
  List<Product> _products = [
    Product(
      id: 'p1',
      title: 'Red Shirt',
      desc: 'A red shirt - it is pretty red!',
      price: 29.99,
      imgURL:
          'https://cdn.pixabay.com/photo/2020/05/07/07/25/woman-5140454_960_720.jpg',
    ),
    Product(
      id: 'p2',
      title: 'Sport Wear',
      desc: 'A good sport',
      price: 59.99,
      imgURL:
          'https://cdn.pixabay.com/photo/2017/12/17/08/01/asia-3023824_960_720.jpg',
    ),
    Product(
      id: 'p3',
      title: 'MackBook',
      desc: 'MacBook not Surface',
      price: 1000.99,
      imgURL:
          'https://cdn.pixabay.com/photo/2014/05/02/21/47/workstation-336369_960_720.jpg',
    ),
    Product(
      id: 'p4',
      title: 'Royal Enfield',
      desc: 'Born to ride..',
      price: 3049.99,
      imgURL:
          'https://cdn.pixabay.com/photo/2015/08/27/09/06/bike-909690_960_720.jpg',
    ),
  ];

  List<Product> get productsList {
    return [..._products];
  }

  List<Product> get productsFav {
    return _products.where((element) => element.isFav).toList();
  }

  Product findById(String pid) {
    return _products.firstWhere((el) => el.id == pid);
  }

  void addProduct() {
    //_products.add('a');
    notifyListeners();
  }
}
Sharing is caring:

Leave a Comment