Flutter - 使用 ListView.builder 索引和提供程序包从列表中删除项目

Flutter - removing an item from a list using ListView.builder index and Provider Package

我是 Flutter 新手,使用 listview.builder 从列表中删除项目时遇到问题。

我正在制作一个 e-commerce 应用程序,我现在有两个页面:i)'main-product-overview page', ii)'product-favorite page'.

问题出在 'product-favorite page'。因此,每当用户在 'main product-overview page' 中按下 'favorite iconbutton' 时,所选产品将存储在产品 class 的列表中(List _favoriteProducts = []; 参见代码下面 ) 并显示在 'product-favorite page' 中。现在,在 'product-favorite page' 中,您也可以取消收藏该产品,但每当我尝试从 'product-favorite-page' 中取消收藏时,该产品不会被删除,或者会以一种奇怪的方式被删除。

这是最喜欢的屏幕的代码 :

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

class FavoriteScreen extends StatefulWidget {
  static const routeName = '/favorite-screen';

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

class _FavoriteScreenState extends State<FavoriteScreen> {
  @override
  Widget build(BuildContext context) {
    final products = Provider.of<Products>(context, listen: false);
    products.changeShowFavorites();
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        toolbarHeight: 80,
        elevation: 0,
      ),
      body: Column(
        children: [
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: [
              Text(
                'Your Favorites',
                style: TextStyle(
                    fontSize: 25,
                    fontWeight: FontWeight.w900,
                    color: Colors.grey.shade800,
                    letterSpacing: 2.5),
              ),
              Text(
                '${products.favorites.length} shoes',
                style: TextStyle(letterSpacing: 1.3),
              ),
            ],
          ),
          SizedBox(
            height: 20,
          ),
          Expanded(
            child: ListView.builder(
              itemBuilder: (ctx, index) => SizedBox(
                height: 220,
                child: Container(
                  height: 200,
                  child: Center(
                    child: Row(
                      children: [
                        Image.network(
                          products.favorites[index].imageUrl,
                        ),
                        Expanded(
                          child: Container(
                            height: 80,
                            child: Card(
                              elevation: 6,
                              shadowColor: Colors.pink,
                              child: InkWell(
                                onTap: () {},
                                child: ListTile(
                                  title: Text(products.favorites[index].title),
                                  trailing: IconButton(
                                    onPressed: () {
                                      setState(() {
                                        products.removeFromFavorite(
                                            products.items[index].id);
                                      });
                                    },
                                    icon: Icon(
                                      Icons.favorite_outlined,
                                      color: Colors.pink,
                                      size: 30,
                                    ),
                                  ),
                                ),
                              ),
                            ),
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
              ),
              itemCount: products.favorites.length,
            ),
          ),
        ],
      ),
    );
  }
}

这是 products_provider

的代码
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import './product.dart';

class Products with ChangeNotifier {
  List<Product> _items = [
    Product(
      id: 'p1',
      title: 'Nike Air Max 90',
      description:
          'Nothing as fly, nothing as comfortable, nothing as proven. The Nike Air Max 90 stays true to its OG running roots with the iconic Waffle sole, stitched overlays and classic TPU details. Classic colors celebrate your fresh look while Max Air cushioning adds comfort to the journey.',
      price: 120.00,
      imageUrl:
          'https://static.nike.com/a/images/t_PDP_1280_v1/f_auto,q_auto:eco/zwxes8uud05rkuei1mpt/air-max-90-mens-shoe-6n3vKB.jpg',
    ),
    Product(
      id: 'p2',
      title: 'Nike Air Max 95',
      description:
          'The Nike Air Max 95 made its mark as the first shoe to include visible Nike Air cushioning in the forefoot. The Nike Air Max 95 SE Men\'s Shoe energizes the iconic design with updated materials in a variety of textures and accents.',
      price: 135.99,
      imageUrl:
          'https://static.nike.com/a/images/t_PDP_1280_v1/f_auto,q_auto:eco/cjao63pcxo42v6y4sfg7/air-max-95-se-mens-shoe-86pJT7.jpg',
    ),
    Product(
      id: 'p3',
      title: 'Nike Air Max 97',
      description:
          'The Nike Air Max 97 reimagines an iconic running shoe into everyday kicks for kids. With classic water ripple-inspired lines, Max Air cushioning and a durable design, it’s all about bringing a ‘90s fave to a new generation.',
      price: 107.99,
      imageUrl:
          'https://static.nike.com/a/images/t_PDP_1280_v1/f_auto,q_auto:eco/93a42f0a-32ee-4dec-9abe-af669f725b0e/air-max-97-big-kids-shoe-fQk07c.jpg',
    ),
    Product(
      id: 'p4',
      title: 'Nike Air Max 270',
      description:
          'Nike\'s first lifestyle Air Max brings you style, comfort and big attitude in the Nike Air Max 270. The design draws inspiration from Air Max icons, showcasing Nike\'s greatest innovation with its large window and fresh array of colors.',
      price: 140.99,
      imageUrl:
          'https://static.nike.com/a/images/t_PDP_1280_v1/f_auto,q_auto:eco/b089e489-b1e5-4bf0-bc41-cc0168d65b02/air-max-270-react-se-shoe-dr3Pn3.jpg',
    ),
  ];

  List<Product> _favoriteProducts = [];

  var _showFavorites = false;

  List<Product> get items {
    return [
      ..._items
    ]; //[..._items] means we are returning a copy of _items rather than the original items
  }

  Product findById(String id) {
    return _items.firstWhere((prod) => prod.id == id);
  }

  List<Product> get favorites {
    if (_showFavorites) {
      return _favoriteProducts;
    }
  }

  void addFavorites(Product product) {
    if (!_favoriteProducts.contains(product) && product.isFavorite == true) {
      _favoriteProducts.add(product);
    }
    notifyListeners();
  }

  void changeShowFavorites() {
    _showFavorites = true;
    notifyListeners();
  }

  void removeFromFavorite(String id) {
    Product toRemoveProduct =
        _favoriteProducts.firstWhere((prod) => prod.id == id);
    toRemoveProduct.isFavorite = false;
    _favoriteProducts.remove(toRemoveProduct);
    notifyListeners();
  }
}

如有任何帮助,我们将不胜感激。如果问题看起来很混乱,我很抱歉。这是我第一次在 Whosebug 上提问。

因为您已经使用了 listen: false 这不会重建小部件, 将其更改为 true 将解决问题