更新 UI 时出错,setState() 在颤动中不起作用

时间:2021-04-28 11:17:34

标签: flutter dart setstate

我在颤动屏幕上有两个按钮(add to cartremove from cart)。 cartQuantity 是我在 build() 方法中声明的一个变量,用于跟踪用户购物车数量。

当用户按下添加按钮时,quantity x rate 的 UI 应该发生变化,这似乎没有发生。

Row 小部件分别包含“删除”按钮、用户购物车数量和“添加”按钮。

class ItemBottomSheet extends StatefulWidget {
  final RestaurantItems restaurantItem;
  final Restaurant restaurant;
  const ItemBottomSheet({
    this.restaurantItem,
    this.restaurant,
  });

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

class _ItemBottomSheetState extends State<ItemBottomSheet> {
  @override
  Widget build(BuildContext context) {
    final size = MediaQuery.of(context).size;
    final cartItems = Provider.of<Cart>(context).getCartItems;
    final index = cartItems.indexWhere((cartItem) =>
        cartItem.id == widget.restaurantItem.id &&
        cartItem.restaurantId == widget.restaurant.id);
    int restQuantity = widget.restaurantItem.quantity;
    int cartQuantity = 0;
    if (index != -1) {
      cartQuantity = cartItems[index].quantity;
    }

    return Container(
      decoration: new BoxDecoration(
          color: darkThemeColour,
          borderRadius: new BorderRadius.only(
              topLeft: const Radius.circular(20.0),
              topRight: const Radius.circular(20.0))),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          Container(
            decoration: new BoxDecoration(
                color: Colors.transparent,
                borderRadius: new BorderRadius.only(
                    topLeft: const Radius.circular(20.0),
                    topRight: const Radius.circular(20.0))),
            height: size.height * 0.21,
            width: double.infinity,
            child: ClipRRect(
              borderRadius: BorderRadius.only(
                  topLeft: Radius.circular(20), topRight: Radius.circular(20)),
              child: Image.network(
                widget.restaurantItem.imageUrl,
                fit: BoxFit.cover,
              ),
            ),
          ),
          Row(
            // crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              // SizedBox(
              //   height: 12,
              //   width: 12,
              //   child: SvgPicture.asset(
              //     'lib/assets/icons/green-circle.svg',
              //     color: restaurantItem.isVeg ? Colors.green : Colors.red,
              //   ),
              // ),
              Padding(
                padding: const EdgeInsets.only(top: 25, left: 18),
                child: Text(
                  widget.restaurantItem.name,
                  style: TextStyle(
                      color: Colors.white,
                      fontFamily: 'Raleway',
                      fontSize: 21,
                      fontWeight: FontWeight.w600),
                ),
              ),
            ],
          ),
          Padding(
            padding: const EdgeInsets.only(top: 17),
            child: Text(
              '₹${widget.restaurantItem.price}',
              style: TextStyle(
                  color: Colors.green,
                  fontFamily: 'Raleway',
                  fontSize: 18,
                  fontWeight: FontWeight.w900),
            ),
          ),
          Padding(
            padding: const EdgeInsets.only(top: 27),
            child: Text(
              'Pickup Between',
              style: TextStyle(
                  color: Colors.white,
                  fontFamily: 'Raleway',
                  fontSize: 14,
                  fontWeight: FontWeight.w300),
            ),
          ),
          Padding(
            padding: const EdgeInsets.only(top: 15),
            child: Text(
              '${DateFormat.jm().format(widget.restaurant.pickupTime.start)}  -  ${DateFormat.jm().format(widget.restaurant.pickupTime.end)}',
              style: TextStyle(
                  color: Colors.white,
                  fontFamily: 'Raleway',
                  fontSize: 17,
                  fontWeight: FontWeight.w400),
            ),
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            crossAxisAlignment: CrossAxisAlignment.end,
            children: [
              Padding(
                padding: const EdgeInsets.only(top: 25, left: 18),
                child: ClipOval(
                  child: Material(
                    color: index == -1 ||
                            cartItems[index].quantity == 0 ||
                            widget.restaurantItem.quantity <= 1
                        ? Colors.grey
                        : Colors.green, // button color
                    child: InkWell(
                      splashColor: Colors.white30, // inkwell color
                      child: SizedBox(
                          width: 60,
                          height: 60,
                          child: Icon(
                            Icons.remove,
                            color: Colors.white,
                            size: 28,
                          )),
                      onTap: () {},
                    ),
                  ),
                ),
              ),
              Padding(
                padding: const EdgeInsets.only(bottom: 20),
                child: Text(
                  cartQuantity > 0
                      ? '$cartQuantity x ₹${widget.restaurantItem.price}'
                      : '₹${widget.restaurantItem.price}',
                  style: TextStyle(
                      color: Colors.white,
                      fontFamily: 'Raleway',
                      fontSize: 22,
                      fontWeight: FontWeight.w900),
                ),
              ),
              Padding(
                padding: const EdgeInsets.only(top: 25, right: 18),
                child: ClipOval(
                  child: Material(
                    color: widget.restaurantItem.quantity <= 1
                        ? Colors.grey
                        : Colors.green, // button color
                    child: InkWell(
                      splashColor: Colors.white30, // inkwell color
                      child: SizedBox(
                          width: 56,
                          height: 56,
                          child: Icon(
                            Icons.add,
                            color: Colors.white,
                          )),
                      onTap: () {
                        setState(() {
                          cartQuantity++;
                          print(cartQuantity.toString());
                        });
                      },
                    ),
                  ),
                ),
              ),
            ],
          ),
          FillButton(
            text: 'ADD TO CART',
            function: () {
              // setState(() {
              //   cartQuantity++;
              // });
            },
          ),
          Padding(
            padding: const EdgeInsets.only(top: 20),
            child: Text(
              widget.restaurantItem.isVeg ? 'VEG' : 'NON - VEG',
              style: TextStyle(
                  fontFamily: 'Raleway',
                  fontSize: 17,
                  fontWeight: FontWeight.w800,
                  color:
                      widget.restaurantItem.isVeg ? Colors.green : Colors.red),
            ),
          ),
          Container(
            height: size.height * 0.3,
            color: darkThemeColour,
          )
        ],
      ),
    );
  }
}

1 个答案:

答案 0 :(得分:1)

您的问题是因为在您的构建中,您每次重建小部件时都会将您的 cartQuantity 初始化为 0。您应该在构建之外对其进行初始化。

class _ItemBottomSheetState extends State<ItemBottomSheet> {

  int cartQuantity = 0;

  @override
  Widget build(BuildContext context) {
    final size = MediaQuery.of(context).size;
    final cartItems = Provider.of<Cart>(context).getCartItems;
    final index = cartItems.indexWhere((cartItem) =>
        cartItem.id == widget.restaurantItem.id &&
        cartItem.restaurantId == widget.restaurant.id);
    int restQuantity = widget.restaurantItem.quantity;

现在您的值不会总是 0,因为您在构建小部件时对其进行了初始化。每次调用 setState 时,都会进行一次重建,然后构建会被调用。

相关问题