簡體   English   中英

Flutter 導航到新頁面拋出錯誤

[英]Flutter Navigation to new page throwing error

我已經通過 JSON 數據創建了 Gridview 構建器,但是當我導航到新頁面時,出現錯誤:無法在此 SingleItemScreen 小部件上方找到正確的提供程序

要修復,請:

  • 確保 Provider 是此 SingleItemScreen Widget 的祖先
  • 向 Provider 提供類型
  • 向消費者提供類型
  • 向 Provider.of() 提供類型
  • 確保使用正確的context

我不確定我哪里出錯了。

List<Product> productFromJson(String str) => List<Product>.from(json.decode(str).map((x) => Product.fromJson(x)));

String productToJson(List<Product> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class Product {
  String productId;
  String sku;
  String itemName;
  String listPrice;
  String publishedPrice;
  String onsale;
  String stockQuantity;
  StockStatus stockStatus;
  String ratingCount;
  String averageRating;
  String totalSales;
  String imagePath;
  String category;

  Product({
    this.productId,
    this.sku,
    this.itemName,
    this.listPrice,
    this.publishedPrice,
    this.onsale,
    this.stockQuantity,
    this.stockStatus,
    this.ratingCount,
    this.averageRating,
    this.totalSales,
    this.imagePath,
    this.category,
  });

  factory Product.fromJson(Map<String, dynamic> json) => Product(
    productId: json["product_id"],
    sku: json["sku"],
    itemName: json["item_name"],
    listPrice: json["list_price"],
    publishedPrice: json["published_price"],
    onsale: json["onsale"],
    stockQuantity: json["stock_quantity"],
    stockStatus: stockStatusValues.map[json["stock_status"]],
    ratingCount: json["rating_count"],
    averageRating: json["average_rating"],
    totalSales: json["total_sales"],
    imagePath: json["image_path"],
    category: json["category"],
  );

  Map<String, dynamic> toJson() => {
    "product_id": productId,
    "sku": sku,
    "item_name": itemName,
    "list_price": listPrice,
    "published_price": publishedPrice,
    "onsale": onsale,
    "stock_quantity": stockQuantity,
    "stock_status": stockStatusValues.reverse[stockStatus],
    "rating_count": ratingCount,
    "average_rating": averageRating,
    "total_sales": totalSales,
    "image_path": imagePath,
    "category": category,
  };
}

enum StockStatus { INSTOCK }

final stockStatusValues = EnumValues({
  "instock": StockStatus.INSTOCK
});

class EnumValues<T> {
  Map<String, T> map;
  Map<T, String> reverseMap;

  EnumValues(this.map);

  Map<T, String> get reverse {
    if (reverseMap == null) {
      reverseMap = map.map((k, v) => new MapEntry(v, k));
    }
    return reverseMap;
  }
}

Future<List<Product>> fetchPhotos(http.Client client) async {
  final response =
  await client.get('http://flutter.bizsupplier.in/product.php');
  return compute(parsePhotos, response.body);
}

Future<List<Product>> parsePhotos(String responseBody) async {
  final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();
  return parsed.map<Product>((json) => Product.fromJson(json)).toList();
}
    class MyHomePage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return FutureBuilder<List<Product>>(
          future: fetchPhotos(http.Client()),
          builder: (context, snapshot) {
            if (snapshot.hasError) print(snapshot.error);
            if (snapshot.hasData) {
              return PhotosList(product: snapshot.data);
            } else {
              return Center(child: CircularProgressIndicator());
            }
          },
        );
      }
    }

    class PhotosList extends StatelessWidget {
      final List<Product> product;

      PhotosList({Key key, this.product}) : super(key: key);

      @override
      Widget build(BuildContext context) {
        return GridView.builder(
          shrinkWrap: true,
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 2,
          ),
          itemCount: product.length,
          itemBuilder: (context, index) {
            return Card(
              child: Column(
                children: <Widget>[
                  Container(
                    height: 150,
                    child: GestureDetector(
                      onTap: (){
                        Navigator.push(
                            context,
                            MaterialPageRoute(
                                builder: (context) => SingleItemScreen(),
                              settings: RouteSettings(
                                arguments: product[index]
                              )
                            )

                        );
                      },
                        child: Image.network(product[index].imagePath)),
                  ),
                  Expanded(
                    child: Row(
                      crossAxisAlignment: CrossAxisAlignment.center,
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        RaisedButton(
                          onPressed: () {},
                          child: Text('Buy Now'),
                          color: Colors.redAccent,
                        ),
                      ],
                    ),
                  )
                ],
              ),
            );
          },
        );
      }
    }


    class SingleItemScreen extends StatelessWidget {
      final List<Product> product;
      SingleItemScreen({Key key, this.product}) : super(key: key);

      @override
      Widget build(BuildContext context) {
        final Product product = Provider.of<Product>(context, listen: false);
        return Scaffold(
            appBar: AppBar(
              title: Text('Test PhP Navigation'),
              actions: <Widget>[
                new IconButton(
                    icon: Icon(
                      Icons.search,
                      color: Colors.white,
                    ),
                    onPressed: () {}),
                new IconButton(
                    icon: Icon(
                      Icons.shopping_cart,
                      color: Colors.white,
                    ),
                    onPressed: () {}),

              ],
            ),
            body: SingleChildScrollView(
              child: Column(
                children: <Widget>[
                  Container(
                    height: 300,
                    child: Image.network(product.imagePath),
                  ),
                  Container(
                    child: Text(product.productId),
                  ),
                ],
              ),
            ),
            bottomNavigationBar: Container(
              width: MediaQuery.of(context).size.width,
              height: 50.0,
              child: Row(
                mainAxisSize: MainAxisSize.max,
                mainAxisAlignment: MainAxisAlignment.spaceAround,
                children: <Widget>[
                  Flexible(
                    fit: FlexFit.tight,
                    flex: 1,
                    child: RaisedButton(
                      onPressed: () {},
                      color: Colors.grey,
                      child: Center(
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: <Widget>[
                            Icon(
                              Icons.list,
                              color: Colors.white,
                            ),
                            SizedBox(
                              width: 4.0,
                            ),
                            Text(
                              "SAVE",
                              style: TextStyle(color: Colors.white),
                            ),
                          ],
                        ),
                      ),
                    ),
                  ),
                  Flexible(
                    flex: 2,
                    child: RaisedButton(
                      onPressed: (){},
                      color: Colors.greenAccent,
                      child: Center(
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: <Widget>[
                            Icon(
                              Icons.card_travel,
                              color: Colors.white,
                            ),
                            SizedBox(
                              width: 4.0,
                            ),
                            Text(
                              "ADD TO BAG",
                              style: TextStyle(color: Colors.white),
                            ),
                          ],
                        ),
                      ),
                    ),
                  ),
                ],
              ),
            ));
      }
    }


您可以在下面復制粘貼運行完整代碼

第一步:備注settings並使用SingleItemScreen(product: product[index])

MaterialPageRoute(
                            builder: (context) =>
                                SingleItemScreen(product: product[index]),
                            /*settings: RouteSettings(
                                  arguments: product[index]
                              )*/
                          ));

第 2 步:修改SingleItemScreen以接受product

class SingleItemScreen extends StatelessWidget {
  final Product product;
  SingleItemScreen({Key key, this.product}) : super(key: key);

第 3 步:備注Provider

//final Product product = Provider.of<Product>(context, listen: false);  

工作演示

在此處輸入圖像描述

完整代碼

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;

List<Product> productFromJson(String str) =>
    List<Product>.from(json.decode(str).map((x) => Product.fromJson(x)));

String productToJson(List<Product> data) =>
    json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class Product {
  String productId;
  String sku;
  String itemName;
  String listPrice;
  String publishedPrice;
  String onsale;
  String stockQuantity;
  StockStatus stockStatus;
  String ratingCount;
  String averageRating;
  String totalSales;
  String imagePath;
  String category;

  Product({
    this.productId,
    this.sku,
    this.itemName,
    this.listPrice,
    this.publishedPrice,
    this.onsale,
    this.stockQuantity,
    this.stockStatus,
    this.ratingCount,
    this.averageRating,
    this.totalSales,
    this.imagePath,
    this.category,
  });

  factory Product.fromJson(Map<String, dynamic> json) => Product(
        productId: json["product_id"],
        sku: json["sku"],
        itemName: json["item_name"],
        listPrice: json["list_price"],
        publishedPrice: json["published_price"],
        onsale: json["onsale"],
        stockQuantity: json["stock_quantity"],
        stockStatus: stockStatusValues.map[json["stock_status"]],
        ratingCount: json["rating_count"],
        averageRating: json["average_rating"],
        totalSales: json["total_sales"],
        imagePath: json["image_path"],
        category: json["category"],
      );

  Map<String, dynamic> toJson() => {
        "product_id": productId,
        "sku": sku,
        "item_name": itemName,
        "list_price": listPrice,
        "published_price": publishedPrice,
        "onsale": onsale,
        "stock_quantity": stockQuantity,
        "stock_status": stockStatusValues.reverse[stockStatus],
        "rating_count": ratingCount,
        "average_rating": averageRating,
        "total_sales": totalSales,
        "image_path": imagePath,
        "category": category,
      };
}

enum StockStatus { INSTOCK }

final stockStatusValues = EnumValues({"instock": StockStatus.INSTOCK});

class EnumValues<T> {
  Map<String, T> map;
  Map<T, String> reverseMap;

  EnumValues(this.map);

  Map<T, String> get reverse {
    if (reverseMap == null) {
      reverseMap = map.map((k, v) => new MapEntry(v, k));
    }
    return reverseMap;
  }
}

Future<List<Product>> fetchPhotos(http.Client client) async {
  final response =
      await client.get('http://flutter.bizsupplier.in/product.php');
  return compute(parsePhotos, response.body);
}

Future<List<Product>> parsePhotos(String responseBody) async {
  final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();
  return parsed.map<Product>((json) => Product.fromJson(json)).toList();
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return FutureBuilder<List<Product>>(
      future: fetchPhotos(http.Client()),
      builder: (context, snapshot) {
        if (snapshot.hasError) print(snapshot.error);
        if (snapshot.hasData) {
          return PhotosList(product: snapshot.data);
        } else {
          return Center(child: CircularProgressIndicator());
        }
      },
    );
  }
}

class PhotosList extends StatelessWidget {
  final List<Product> product;

  PhotosList({Key key, this.product}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return GridView.builder(
      shrinkWrap: true,
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
      ),
      itemCount: product.length,
      itemBuilder: (context, index) {
        return Card(
          child: Column(
            children: <Widget>[
              Container(
                height: 150,
                child: GestureDetector(
                    onTap: () {
                      Navigator.push(
                          context,
                          MaterialPageRoute(
                            builder: (context) =>
                                SingleItemScreen(product: product[index]),
                            /*settings: RouteSettings(
                                  arguments: product[index]
                              )*/
                          ));
                    },
                    child: Image.network(product[index].imagePath)),
              ),
              Expanded(
                child: Row(
                  crossAxisAlignment: CrossAxisAlignment.center,
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    RaisedButton(
                      onPressed: () {},
                      child: Text('Buy Now'),
                      color: Colors.redAccent,
                    ),
                  ],
                ),
              )
            ],
          ),
        );
      },
    );
  }
}

class SingleItemScreen extends StatelessWidget {
  final Product product;
  SingleItemScreen({Key key, this.product}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    //final Product product = Provider.of<Product>(context, listen: false);
    return Scaffold(
        appBar: AppBar(
          title: Text('Test PhP Navigation'),
          actions: <Widget>[
            new IconButton(
                icon: Icon(
                  Icons.search,
                  color: Colors.white,
                ),
                onPressed: () {}),
            new IconButton(
                icon: Icon(
                  Icons.shopping_cart,
                  color: Colors.white,
                ),
                onPressed: () {}),
          ],
        ),
        body: SingleChildScrollView(
          child: Column(
            children: <Widget>[
              Container(
                height: 300,
                child: Image.network(product.imagePath),
              ),
              Container(
                child: Text(product.productId),
              ),
            ],
          ),
        ),
        bottomNavigationBar: Container(
          width: MediaQuery.of(context).size.width,
          height: 50.0,
          child: Row(
            mainAxisSize: MainAxisSize.max,
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: <Widget>[
              Flexible(
                fit: FlexFit.tight,
                flex: 1,
                child: RaisedButton(
                  onPressed: () {},
                  color: Colors.grey,
                  child: Center(
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        Icon(
                          Icons.list,
                          color: Colors.white,
                        ),
                        SizedBox(
                          width: 4.0,
                        ),
                        Text(
                          "SAVE",
                          style: TextStyle(color: Colors.white),
                        ),
                      ],
                    ),
                  ),
                ),
              ),
              Flexible(
                flex: 2,
                child: RaisedButton(
                  onPressed: () {},
                  color: Colors.greenAccent,
                  child: Center(
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        Icon(
                          Icons.card_travel,
                          color: Colors.white,
                        ),
                        SizedBox(
                          width: 4.0,
                        ),
                        Text(
                          "ADD TO BAG",
                          style: TextStyle(color: Colors.white),
                        ),
                      ],
                    ),
                  ),
                ),
              ),
            ],
          ),
        ));
  }
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(),
    );
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM