繁体   English   中英

Flutter 错误:找不到正确的提供程序<cart>在此 ProductLandingPage 小部件上方</cart>

[英]Flutter Error : Could not find the correct Provider<Cart> above this ProductLandingPage Widget

我正在创建一个电子商务应用程序,其中主页是一种页面,其中提供了所有字段,如类别和其他信息。

这是我的屏幕流程... HomeScreen -> CategoryPage -> ProductByCategory -> ProductLandingPage

我收到错误。 第一次接触编码和学习提供者,无法解决此问题。

错误:在此 ProductLandingPage 小部件上方找不到正确的提供程序

要修复,请:

  • 确保 Provider 是此 ProductLandingPage 小部件的祖先
  • 向 Provider 提供类型
  • 向消费者提供类型
void main() {
  runApp(MaterialApp(
    home: MultiProvider(
      providers: [
        ChangeNotifierProvider.value(
          value: Cart(),
        )
      ],
      child: HomeScreen(),
    ),
    debugShowCheckedModeBanner: false,
  ));
}
class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  @override
  Widget build(BuildContext context) {


    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.redAccent,
        title: Text('Factory2Homes'),
        actions: <Widget>[
          IconButton(icon: Icon(Icons.search), onPressed: () {}),
          Consumer<Cart>(
            builder: (_, cart, ch) => Badge(
              child: ch,
              value: cart.itemCount.toString(),
            ),
            child: IconButton(
              icon: Icon(
                Icons.shopping_cart,
              ),
              onPressed: () {
              },
            ),
          ),
        ],
      ),
      body: SingleChildScrollView(
        child: Column(
          children: <Widget>[


            Container(height: 500, child: CategoryPage()),
          ],
        ),
      ),
    );
  }
}
class CategoryPage extends StatefulWidget {
  @override
  _CategoryPageState createState() => _CategoryPageState();
}

class _CategoryPageState extends State<CategoryPage> {
  @override
  Widget build(BuildContext context) {



    return FutureBuilder<List<AllCategory>>(

      future: getCategoryList(http.Client()),
      builder: (context, snapshot) {
        if (snapshot.hasError) print(snapshot.error);
        return snapshot.hasData
            ? ListOfCategories(
                categories: snapshot.data,
              )
            : Center(
                child: CircularProgressIndicator(
                backgroundColor: Colors.red,
              ));
      },
    );
  }
}

class ListOfCategories extends StatelessWidget {
  final List<AllCategory> categories;
  ListOfCategories({this.categories});

  @override
  Widget build(BuildContext context) {



    return GridView.builder(
      physics: NeverScrollableScrollPhysics(),
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(

        crossAxisCount: 2,

      ),
      itemCount: categories.length,
      itemBuilder: (context, index) {



        return InkWell(
          onTap: (){
            Navigator.push(context, MaterialPageRoute(builder: (context) => ProductByCategory(category: categories[index],)));

          },

            child: Image.network(categories[index].categoryIcon));
      },
    );
  }
}
class ProductByCategory extends StatefulWidget {
  final AllCategory category;
  final CarouselSlider carouselslider;

  ProductByCategory({this.category, this.carouselslider});

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

class _ProductByCategoryState extends State<ProductByCategory> {
  @override
  Widget build(BuildContext context) {



    return Scaffold(
      appBar: AppBar(
        actions: <Widget>[
          Consumer<Cart>(
            builder: (_, cart, ch) => Badge(
              child: ch,
              value: cart.itemCount.toString(),
            ),
            child: IconButton(
              icon: Icon(
                Icons.shopping_cart,
              ),
              onPressed: () {
              },
            ),
          ),
          IconButton(icon: Icon(Icons.search), onPressed: () {}),
        ],
      ),
      body: FutureBuilder<List<Product>>(
        future: getCategoryByProduct(http.Client(), widget.category.id),
        builder: (context, snapshot) {

          if (snapshot.hasError) print(snapshot.error);
          if (snapshot.hasData) {
            return ProductByCategoryScreen(
              product: snapshot.data,
            );
          } else {
            return Center(child: CircularProgressIndicator());
          }
        },
      ),
    );
  }
}

class ProductByCategoryScreen extends StatefulWidget {
  final List<Product> product;

  ProductByCategoryScreen({this.product});

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

class _ProductByCategoryScreenState extends State<ProductByCategoryScreen> {
  @override
  Widget build(BuildContext context) {



    return GridView.builder(
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
      ),
      itemCount: widget.product.length,
      itemBuilder: (context, index) {

        return InkWell(
            onTap: () {
              Navigator.push(
                  context,
                  MaterialPageRoute(
                      builder: (context) =>
                          ProductLandingPage(widget.product[index])));
            },
            child:
                Card(child: Image.network(widget.product[index].productPhoto)));
      },
    );
  }
}
class ProductLandingPage extends StatefulWidget {
  final Product product;

  ProductLandingPage(this.product);

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

class _ProductLandingPageState extends State<ProductLandingPage> {


  @override
  Widget build(BuildContext context) {
    final cart = Provider.of<Cart>(context, listen: false);


    return Scaffold(
        appBar: AppBar(
          actions: <Widget>[

          ],
        ),
        body: SingleChildScrollView(
          child: Column(
            children: <Widget>[
              Container(
                color: Colors.green,
                height: MediaQuery.of(context).size.height / 2,
                child: Padding(
                  padding: const EdgeInsets.only(top: 8.0),
                  child: Image.network(widget.product.productPhoto),
                ),
              ),
              Divider(
                thickness: 1,
              ),
              Container(
                child: Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Text(this.widget.product.productName),
                ),
              ),
              Divider(),
              Container(
                child: Row(
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: <Widget>[
                    Column(
                      children: <Widget>[
                        Padding(
                          padding: const EdgeInsets.only(left: 10.0),
                          child: Text(
                            '₹' + '${this.widget.product.productSalePrice}',
                            style: TextStyle(
                                fontSize: 30, fontWeight: FontWeight.w500),
                          ),
                        ),
                      ],
                    ),
                    Padding(
                      padding: const EdgeInsets.only(left: 8.0),
                      child: Center(
                        child: Text(
                            'MRP:' + '${this.widget.product.productListPrice}'),
                      ),
                    ),
                  ],
                ),
              ),
              Divider(),
              Row(
                mainAxisAlignment: MainAxisAlignment.start,
                children: <Widget>[
                  Padding(
                    padding: const EdgeInsets.only(left: 10.0),
                    child: Text(
                      'Description',
                      style:
                          TextStyle(fontSize: 18, fontWeight: FontWeight.w500),
                    ),
                  ),
                ],
              ),
              Container(
                child: Padding(
                  padding: const EdgeInsets.all(10.0),
                  child: Text(this.widget.product.productDescription),
                ),
              ),
            ],
          ),
        ),
        bottomNavigationBar: Container(
          width: MediaQuery.of(context).size.width,
          height: 45.0,
          child: RaisedButton(
            onPressed: () {
           cart.addItem(
               '${widget.product.productId}',
               widget.product.productListPrice,
               widget.product.productName,
            );
            },
            color: Colors.redAccent,
            child: Center(
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Icon(
                    Icons.card_travel,
                    color: Colors.white,
                  ),
                  SizedBox(
                    width: 4.0,
                  ),
                  Text(
                    "ADD TO CART",
                    style: TextStyle(color: Colors.white),
                  ),
                ],
              ),
            ),
          ),
        ));
  }
}
class CartItem {
  final String id;
  final String title;
  final int quantity;
  final int price;

  CartItem({
    this.id,
    this.title,
    this.quantity,
    this.price,
  });
}

class Cart with ChangeNotifier {
  Map<String, CartItem> _items;

  Map<String, CartItem> get items {
    return {..._items};
  }

  int get itemCount{
    return _items==null ?0 :_items.length;
  }

  void addItem(
    String productId,
    int productListPrice,
    String productName,
  ) {
    if (_items.containsKey(productId)) {
      _items.update(
          productId,
          (existingCartItem) => CartItem(
                id: existingCartItem.id,
                title: existingCartItem.title,
                price: existingCartItem.price,
                quantity: existingCartItem.quantity + 1,
              ));
    } else {
      _items.putIfAbsent(
          productId,
          () => CartItem(
                id: DateTime.now().toString(),
                title: productName,
                price: productListPrice,
                quantity: 1,
              ));
    }
  }
}

Provider 的想法是将 state 管理提升到小部件之上,以便不同的孩子可以轻松访问其 state。 因此,如果您将 HTTP 请求从小部件树(每次 UI 更新时都会调用它,因此用户使用的带宽超过所需的带宽)移动到在树上方创建的提供程序,将会很有帮助。 因此 state 不需要在小部件之间传递。

尝试观看 flutter 团队的精彩演讲,以更好地了解如何使用提供程序: https://youtu.be/d_m5csmrf7I

Bdw 阅读了这个 StackOverflow 答案,了解为什么.value不是您想要的: 如何处理不需要的小部件构建?

所以你应该制作这样的应用程序

void main() => runApp(MyApp());


class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => Cart(),
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'Factory2Homes',
        home: HomeScreen(),
      ),
    );
  }
}

我通过将 main.dart 代码更改为以下代码使其工作:

void main() => runApp(MyApp());


class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider.value(value: Cart(),
      child:MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'Factory2Homes',
        home: HomeScreen(),
      ),);
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM