Как мне сделать мою корзину одинаковой при доступе со всех страниц

#flutter #dart

#flutter #dart

Вопрос:

Как мне сделать мою корзину одинаковой при доступе со всех страниц?

У меня есть разные категории напитков из разных классов, и все товары из этих классов можно добавить в корзину, но когда я нажимаю на значок корзины на панели приложений со страницы, на которой я нахожусь, я вижу только товары со страницы, на которой я нахожусь, а не значки со всех разных категории

Страница корзины

 import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'dish_object.dart';

class Cart extends StatefulWidget {
  final List<Drinks> _cart;
  Cart(this._cart);

  @override
  _CartState createState() => _CartState(this._cart);
}

class _CartState extends State<Cart> {
  _CartState(this._cart);

  List<Drinks> _cart;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.redAccent[100],
        title: Text(
          'Cart',
          style: TextStyle(fontSize: 20, fontWeight: FontWeight.normal),
        ),
        actions: <Widget>[
          IconButton(
              icon: Icon(Icons.send_rounded),
              tooltip: "Confirm Order",
              onPressed: () {
                if (_cart.isNotEmpty) {
                  setState(() {
                    Fluttertoast.showToast(
                        msg: "Order Confirmed",
                        toastLength: Toast.LENGTH_LONG,
                        gravity: ToastGravity.BOTTOM,
                        timeInSecForIosWeb: 1,
                        backgroundColor: Colors.green[200],
                        textColor: Colors.white,
                        fontSize: 16.0);
                  });
                }
                if (_cart.isEmpty) {
                  setState(() {
                    Fluttertoast.showToast(
                        msg: "Cart Empty",
                        toastLength: Toast.LENGTH_LONG,
                        gravity: ToastGravity.BOTTOM,
                        timeInSecForIosWeb: 1,
                        backgroundColor: Colors.red,
                        textColor: Colors.white,
                        fontSize: 16.0);
                  });
                }
              }),
          if (_cart.length > 0)
            Padding(
              padding: const EdgeInsets.only(right: 5.0, bottom: 10.0),
              child: CircleAvatar(
                radius: 10.0,
                backgroundColor: Colors.red,
                foregroundColor: Colors.white,
                child: Text(
                  _cart.length.toString(),
                  style: TextStyle(
                    fontWeight: FontWeight.bold,
                    fontSize: 12.0,
                  ),
                ),
              ),
            ),
        ],
      ),
      body: ListView.builder(
        itemCount: _cart.length   1,
        itemBuilder: (context, index) {
          if (index == _cart.length)
            return Align(
              alignment: Alignment.bottomLeft,
              child: Padding(
                padding:
                    const EdgeInsets.symmetric(horizontal: 10.0, vertical: 2.0),
                child: Card(
                  shape: RoundedRectangleBorder(
                    borderRadius: new BorderRadius.circular(18.0),
                  ),
                  elevation: 4.0,
                  child: Text(
                      "Cart Total: R"  
                          _cart
                              .fold<int>(0, (a, b) => a   b.totalPrice())
                              .toString(),
                      style: TextStyle(
                          fontWeight: FontWeight.w500,
                          fontSize: 25,
                          color: Colors.redAccent[200])),
                ),
              ),
            );
          var item = _cart[index];
          return Padding(
            padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 1.0),
            child: Card(
              elevation: 4.0,
              child: ListTile(
                //Leading
                leading: Text(
                  item.category   "n"   "R"   item.price.toString(),
                ),

                //Title
                title: Text(item.brandName  
                    "n"  
                    "("  
                    item.counter.toString()  
                    ")"),
                //Subtitle
                subtitle: GestureDetector(
                  child: Icon(
                    Icons.add,
                    color: Colors.green,
                  ),
                  onTap: () {
                    setState(() {
                      item.incrementCounter();
                    });
                  },
                ),

                //Trailing
                trailing: GestureDetector(
                  child: Icon(
                    Icons.remove_circle,
                    color: Colors.red,
                  ),
                  onTap: () {
                    setState(() {
                      item.decrementCounter();
                    });
                  },
                ),
                isThreeLine: true,
              ),
            ),
          );
        },
      ),
    );
  }
}
 

Класс категории джин-коктейли

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

import 'cart.dart';
import 'dish_object.dart';
import 'main_drawer.dart';

class ginCocktails extends StatefulWidget {
  ginCocktails({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _ginCocktailsState createState() => _ginCocktailsState();
}

class _ginCocktailsState extends State<ginCocktails> {
  List<Drinks> _dishes = List<Drinks>();
  List<Drinks> _cartList = List<Drinks>();

  @override
  void initState() {
    super.initState();
    _populateDishes();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Gin Cocktails"),
        actions: <Widget>[
          Padding(
            padding: const EdgeInsets.only(right: 16.0, top: 8.0),
            child: GestureDetector(
              child: Stack(
                alignment: Alignment.topCenter,
                children: <Widget>[
                  Icon(
                    Icons.shopping_basket,
                    size: 35.0,
                  ),
                  if (_cartList.length > 0)
                    Padding(
                      padding: const EdgeInsets.only(left: 2.0),
                      child: CircleAvatar(
                        radius: 8.0,
                        backgroundColor: Colors.red,
                        foregroundColor: Colors.white,
                        child: Text(
                          _cartList.length.toString(),
                          style: TextStyle(
                            fontWeight: FontWeight.bold,
                            fontSize: 12.0,
                          ),
                        ),
                      ),
                    ),
                ],
              ),
              onTap: () {
                if (_cartList.isNotEmpty)
                  Navigator.of(context).push(
                    MaterialPageRoute(
                      builder: (context) => Cart(_cartList),
                    ),
                  );

                setState(() {
                  if (_cartList.isEmpty) {
                    Fluttertoast.showToast(
                        msg: "Cart Empty, Add items to Cart",
                        toastLength: Toast.LENGTH_LONG,
                        gravity: ToastGravity.BOTTOM,
                        timeInSecForIosWeb: 1,
                        backgroundColor: Colors.red,
                        textColor: Colors.white,
                        fontSize: 16.0);
                  }
                });
              },
            ),
          )
        ],
        backgroundColor: Colors.redAccent[100],
      ),
      drawer: MainDrawer(),
      body: _buildGridView(),
    );
  }

  GridView _buildGridView() {
    return GridView.builder(
        padding: const EdgeInsets.all(4.0),
        gridDelegate:
            SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
        itemCount: _dishes.length,
        itemBuilder: (context, index) {
          var item = _dishes[index];
          return Card(
              elevation: 4.0,
              child: Stack(
                fit: StackFit.loose,
                alignment: Alignment.center,
                children: <Widget>[
                  Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      Text(item.category),
                      Text(
                        item.brandName,
                        textAlign: TextAlign.center,
                        style: Theme.of(context).textTheme.subhead,
                      ),
                      Text(
                        "R"   item.price.toString(),
                        textAlign: TextAlign.right,
                      )
                    ],
                  ),
                  Padding(
                    padding: const EdgeInsets.only(
                      right: 8.0,
                      bottom: 8.0,
                    ),
                    child: Align(
                      alignment: Alignment.bottomRight,
                      child: GestureDetector(
                        child: (!_cartList.contains(item))
                            ? Icon(
                                Icons.add_circle,
                                color: Colors.green,
                              )
                            : Icon(
                                Icons.remove_circle,
                                color: Colors.red,
                              ),
                        onTap: () {
                          setState(() {
                            if (!_cartList.contains(item))
                              _cartList.add(item);
                            else
                              _cartList.remove(item);
                          });
                        },
                      ),
                    ),
                  ),
                ],
              ));
        });
  }

  void _populateDishes() {
    var list = <Drinks>[
      Drinks(
        category: 'Gin Cocktails',
        brandName: "Clover Club",
        price: 65,
      ),
      Drinks(
        category: 'Gin Cocktail',
        brandName: 'Tanqueray Sling',
        price: 99,
      ),
      Drinks(
        category: 'Gin Cocktail',
        brandName: 'French 75',
        price: 84,
      ),
      Drinks(
        category: 'Gin Cocktail',
        brandName: '1934 Cosmo',
        price: 85,
      ),
      Drinks(
        category: 'Gin Cocktail',
        brandName: "Sevilla Roseate",
        price: 80,
      ),
      Drinks(
        category: 'Gin Cocktail',
        brandName: 'TWR  Sevilla Gimlet',
        price: 75,
      ),
      Drinks(
        category: 'Gin Cocktail',
        brandName: 'Watermelon Aperol Spiritz ',
        price: 97,
      )
    ];

    setState(() {
      _dishes = list;
    });
  }
}
 

Класс ящика

 import 'package:flutter/material.dart';
import 'package:pass_data/cart.dart';
import 'package:pass_data/ginCocktails.dart';
import 'package:pass_data/whiskeyCocktails.dart';

import 'dish_object.dart';
import 'main.dart';

class MainDrawer extends StatelessWidget {
  List<Drinks> _cartList = List<Drinks>();

  @override
  Widget build(BuildContext context) {
    return Drawer(
        child: SingleChildScrollView(
      child: Column(
        children: <Widget>[
          Container(
            width: double.infinity,
            padding: EdgeInsets.all(20),
            color: Colors.redAccent[100],
            child: Center(
              child: Column(
                children: <Widget>[
                  Container(
                    width: 100,
                    height: 100,
                    margin: EdgeInsets.only(top: 30, bottom: 20),
                    decoration: BoxDecoration(
                        shape: BoxShape.circle,
                        image: DecorationImage(
                            image: AssetImage("lib/twr.png"),
                            fit: BoxFit.fill)),
                  ),
                  Text("The Wing Republic",
                      style: TextStyle(fontSize: 22, color: Colors.white))
                ],
              ),
            ),
          ),
          ListTile(
            leading: Icon(Icons.local_drink),
            title: Text(
              "GIN COCKTAILS",
              style: TextStyle(
                fontSize: 18,
              ),
            ),
            onTap: () {
              Navigator.of(context).push(
                  MaterialPageRoute(builder: (context) => ginCocktails()));
            },
          ),
          ListTile(
            leading: Icon(Icons.local_drink),
            title: Text(
              "WHISK(E)Y COCKTAILS",
              style: TextStyle(
                fontSize: 18,
              ),
            ),
            onTap: () {
              Navigator.of(context).push(
                  MaterialPageRoute(builder: (context) => whiskeyCocktails()));
            },
          ),
          ListTile(
            leading: Icon(Icons.local_drink),
            title: Text(
              "COGNAC/BRANDY",
              style: TextStyle(
                fontSize: 18,
              ),
            ),
            onTap: null,
          ),
          ListTile(
            leading: Icon(Icons.local_drink),
            title: Text(
              "RUM COCKTAILS",
              style: TextStyle(
                fontSize: 18,
              ),
            ),
            onTap: null,
          ),
          ListTile(
            leading: Icon(Icons.local_drink),
            title: Text(
              "TEQUILLA COCKTAILS",
              style: TextStyle(
                fontSize: 18,
              ),
            ),
            onTap: null,
          ),
          ListTile(
            leading: Icon(Icons.local_drink),
            title: Text(
              "Beers amp; Ciders",
              style: TextStyle(
                fontSize: 18,
              ),
            ),
            onTap: null,
          ),
          ListTile(
            leading: Icon(Icons.local_drink),
            title: Text(
              "VODKA COCKTAILS",
              style: TextStyle(
                fontSize: 18,
              ),
            ),
            onTap: null,
          ),
          ListTile(
            leading: Icon(Icons.local_drink),
            title: Text(
              "MOCKTAILS",
              style: TextStyle(
                fontSize: 18,
              ),
            ),
            onTap: null,
          ),
          ListTile(
            leading: Icon(Icons.local_drink),
            title: Text(
              "Beers amp; Ciders",
              style: TextStyle(
                fontSize: 18,
              ),
            ),
            onTap: null,
          ),
          ListTile(
            leading: Icon(Icons.local_drink),
            title: Text(
              "SHOOTERS",
              style: TextStyle(
                fontSize: 18,
              ),
            ),
            onTap: null,
          ),
          ListTile(
            leading: Icon(Icons.local_drink),
            title: Text(
              "BEERS amp; CIDERS",
              style: TextStyle(
                fontSize: 18,
              ),
            ),
            onTap: null,
          ),
          ListTile(
            leading: Icon(Icons.local_drink),
            title: Text(
              "VODKA",
              style: TextStyle(
                fontSize: 18,
              ),
            ),
            onTap: null,
          ),
          ListTile(
            leading: Icon(Icons.local_drink),
            title: Text(
              "LIQUERS",
              style: TextStyle(
                fontSize: 18,
              ),
            ),
            onTap: null,
          ),
          ListTile(
            leading: Icon(Icons.local_drink),
            title: Text(
              "WINE BY THE GLASS",
              style: TextStyle(
                fontSize: 18,
              ),
            ),
            onTap: null,
          ),
          ListTile(
            leading: Icon(Icons.local_drink),
            title: Text(
              "WHITE WINE",
              style: TextStyle(
                fontSize: 18,
              ),
            ),
            onTap: null,
          ),
          ListTile(
            leading: Icon(Icons.local_drink),
            title: Text(
              "RED WINE",
              style: TextStyle(
                fontSize: 18,
              ),
            ),
            onTap: null,
          ),
          ListTile(
            leading: Icon(Icons.local_drink),
            title: Text(
              "MOSCATO | ROSE/BLUSH",
              style: TextStyle(
                fontSize: 18,
              ),
            ),
            onTap: null,
          ),
          ListTile(
            leading: Icon(Icons.local_drink),
            title: Text(
              "BUBBLES",
              style: TextStyle(
                fontSize: 18,
              ),
            ),
            onTap: null,
          ),
          ListTile(
            leading: Icon(Icons.local_drink),
            title: Text(
              "MCC",
              style: TextStyle(
                fontSize: 18,
              ),
            ),
            onTap: null,
          ),
          ListTile(
            leading: Icon(Icons.local_drink),
            title: Text(
              "CHAMPAGNE",
              style: TextStyle(
                fontSize: 18,
              ),
            ),
            onTap: null,
          ),
          ListTile(
            leading: Icon(Icons.local_drink),
            title: Text(
              "COGNAC",
              style: TextStyle(
                fontSize: 18,
              ),
            ),
            onTap: null,
          ),
          ListTile(
            leading: Icon(Icons.local_drink),
            title: Text(
              "TEQUILLA",
              style: TextStyle(
                fontSize: 18,
              ),
            ),
            onTap: null,
          ),
          ListTile(
            leading: Icon(Icons.local_drink),
            title: Text(
              "NON-ALCOHOLIC",
              style: TextStyle(
                fontSize: 18,
              ),
            ),
            onTap: null,
          ),
        ],
      ),
    ));
  }
}
 

Комментарии:

1. поддерживая state!, поместите ваше состояние этой корзины в одноэлементный или одиночный экземпляр, который доступен во всем приложении

2. используйте любое управление состоянием, такое как provider, getX, BLoC, MobX и т.д.

3. … или Риверпод!

Ответ №1:

Рассмотрите возможность использования поставщика и даже пользовательского класса модели корзины, например:

 CartModel{
final String name;
final int quantity;
final int price;

 CartModel(this.name,this.quantity,this.price);
}
 

Корзина теперь может быть представлена в виде списка

Обязательно внедрите пакет поставщика, который можно найти здесь: https://pub.dev/packages/provider

На этом предоставленном URL-адресе вы найдете дополнительную информацию о том, как использовать пакет поставщика. Теперь у вас есть возможность управлять списком корзин с помощью функций внутри класса provider.