【问题标题】:Flutter Navigation to new page throwing error颤振导航到新页面抛出错误
【发布时间】:2020-04-17 07:01:19
【问题描述】:

我已经通过 JSON 数据创建了 Gridview 构建器,但是当我导航到新页面时,出现错误:在此 SingleItemScreen 小部件上方找不到正确的提供程序

要修复,请:

  • 确保 Provider 是此 SingleItemScreen 小部件的祖先
  • 向 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),
                            ),
                          ],
                        ),
                      ),
                    ),
                  ),
                ],
              ),
            ));
      }
    }


【问题讨论】:

    标签: json flutter


    【解决方案1】:

    您可以在下面复制粘贴运行完整代码

    第1步:备注settings并使用SingleItemScreen(product: product[index])

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

    第二步:修改SingleItemScreen接受product

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

    第三步:备注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(),
        );
      }
    }
    

    【讨论】:

    • 完美运行.. 感谢您的快速帮助.. :)
    猜你喜欢
    • 2021-08-07
    • 1970-01-01
    • 1970-01-01
    • 2019-02-01
    • 2021-01-16
    • 2020-07-14
    • 2019-06-30
    • 2020-03-14
    • 1970-01-01
    相关资源
    最近更新 更多