单击 Gridview 项时将数据传递到另一个屏幕

Posted

技术标签:

【中文标题】单击 Gridview 项时将数据传递到另一个屏幕【英文标题】:Pass data to another screen when Gridview item is clicked 【发布时间】:2019-05-08 23:50:17 【问题描述】:

我是一名学习 Flutter 的 Java 开发人员。单击 Gridview 的项目时,我需要将数据传递到另一个屏幕。我尝试了几个在线帮助,但找不到更好的解决方案,

我的课是,

class Product extends StatefulWidget 
  @override
  State<StatefulWidget> createState() 
    return _ProductState();
  


var productList = [
  
    "name": "Product 1",
    "image": "assets/products/product1.jpg",
    "price": 6.99,
    "description": "30% off",
  ,
  .
  .
  .
  .
];

class _ProductState extends State<Product> 
  @override
  Widget build(BuildContext context) 
    return GridView.builder(
      physics: const NeverScrollableScrollPhysics(),
      shrinkWrap: true,
      itemCount: productList.length,
      gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
      ),
      itemBuilder: (BuildContext context, int index) 
        return FeatureProduct(
          productName: productList[index]['name'],
          productImage: productList[index]['image'],
          productPrice: productList[index]['price'],
          productDescription: productList[index]['description'],
        );
      ,
    );
  


class FeatureProduct extends StatelessWidget 
  final String productImage;
  final String productName;
  final String productDescription;
  final double productPrice;

  FeatureProduct(
      this.productImage,
      this.productName,
      this.productPrice,
      this.productDescription);

  @override
  Widget build(BuildContext context) 
    return Card(
      child: Hero(
        tag: productName,
        child: Material(
          child: InkWell(
            onTap: () 
              // print(productName);
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => new ProductDetail(
                        product: FeatureProduct(
                          productName: productName,
                          productImage: productImage,
                          productDescription: productDescription,
                          productPrice: productPrice,
                        ),
                      ),
                ),
              );
            ,
            child: GridTile(
                footer: Container(
                  color: Colors.white70,
                  child: ListTile(
                    leading: Text(
                      productName,
                      style: TextStyle(
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                    title: Text(
                      "RM $productPrice",
                      style: TextStyle(
                        color: Colors.red,
                        fontWeight: FontWeight.w700,
                      ),
                    ),
                    subtitle: Text(
                      productDescription,
                      style: TextStyle(
                        color: Colors.black,
                        fontWeight: FontWeight.w400,
                      ),
                    ),
                  ),
                ),
                child: Padding(
                  padding: EdgeInsets.all(15.0),
                  child: Image.asset(
                    productImage,
                    fit: BoxFit.cover,
                  ),
                )),
          ),
        ),
      ),
    );
  


class ProductDetail extends StatelessWidget 
  final FeatureProduct product;

  ProductDetail(this.product);

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        title: Text("$product.productName"),
      ),
      body: Padding(
        padding: EdgeInsets.all(16.0),
        child: Text('$product.productDescription'),
      ),
    );
  

我在执行上述代码的过程中尝试了以下异常,

I/flutter (7767): ══╡ 调度程序库发现异常 ╞═════════════════════════════════════════════════ ════════ I/flutter (7767):在调度程序回调期间抛出以下断言: I/flutter (7767):在一个子树中有多个英雄共享同一个标签。 I/flutter (7767):在每个要为其动画英雄的子树(通常是 PageRoute 子树)中,每个英雄 I/flutter (7767):必须有一个唯一的非空标签。 I/flutter (7767):在这种情况下,多个英雄具有以下标签:产品 5 I/flutter(7767):这是其中一位违规英雄的子树: 我/颤振(7767):#英雄(标签:产品5,状态:_HeroState#c56bf) 我/颤振(7767):#└KeyedSubtree-[GlobalKey#ef976] I/flutter(7767):#└Material(类型:画布,状态:_MaterialState#d2e02) I/flutter(7767):#└AnimatedPhysicalModel(持续时间:200ms,形状:矩形,borderRadius:BorderRadius.zero,海拔:0.0, 颜色:颜色(0xfffafafa),动画颜色:假,阴影颜色: 颜色(0xff000000),动画阴影颜色:真,状态: _AnimatedPhysicalModelState#8cf00(ticker inactive))

我该如何解决这个问题,请帮助我。

【问题讨论】:

list 中每个产品的 productName 是否唯一? 在您的错误中明确指出 - 在这种情况下,多个英雄具有以下标签:产品 5 【参考方案1】:

为了修复声明的错误,您需要将唯一标记分配给 hero 小部件。

我建议使用 index 值而不是 productName

更新后的代码如下所示:

import 'package:flutter/material.dart';

class Product extends StatefulWidget 
  @override
  State<StatefulWidget> createState() 
    return _ProductState();
  


var productList = [
  
    "name": "Product 1",
    "image": "assets/products/product1.jpg",
    "price": 6.99,
    "description": "30% off",
  ,
  
    "name": "Product 2",
    "image": "assets/products/product1.jpg",
    "price": 6.99,
    "description": "30% off",
  ,
  
    "name": "Product 3",
    "image": "assets/products/product1.jpg",
    "price": 6.99,
    "description": "30% off",
  ,
  
    "name": "Product 4",
    "image": "assets/products/product1.jpg",
    "price": 6.99,
    "description": "30% off",
  ,
];

class _ProductState extends State<Product> 
  @override
  Widget build(BuildContext context) 
    return GridView.builder(
      physics: const NeverScrollableScrollPhysics(),
      shrinkWrap: true,
      itemCount: productList.length,
      gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
      ),
      itemBuilder: (BuildContext context, int index) 
        return FeatureProduct(
          productName: productList[index]['name'],
          productImage: productList[index]['image'],
          productPrice: productList[index]['price'],
          productDescription: productList[index]['description'],
          index: index,
        );
      ,
    );
  


class FeatureProduct extends StatelessWidget 
  final String productImage;
  final String productName;
  final String productDescription;
  final double productPrice;
  final int index;

  FeatureProduct(
      this.productImage,
      this.productName,
      this.productPrice,
      this.index,
      this.productDescription);

  @override
  Widget build(BuildContext context) 
    return Card(
      child: Hero(
        tag: index,
        child: Material(
          child: InkWell(
            onTap: () 
              // print(productName);
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => new ProductDetail(
                        product: FeatureProduct(
                          productName: productName,
                          productImage: productImage,
                          productDescription: productDescription,
                          productPrice: productPrice,
                        ),
                      ),
                ),
              );
            ,
            child: GridTile(
                footer: Container(
                  color: Colors.white70,
                  child: ListTile(
                    leading: Text(
                      productName,
                      style: TextStyle(
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                    title: Text(
                      "RM $productPrice",
                      style: TextStyle(
                        color: Colors.red,
                        fontWeight: FontWeight.w700,
                      ),
                    ),
                    subtitle: Text(
                      productDescription,
                      style: TextStyle(
                        color: Colors.black,
                        fontWeight: FontWeight.w400,
                      ),
                    ),
                  ),
                ),
                child: Padding(
                  padding: EdgeInsets.all(15.0),
                  child: Image.asset(
                    productImage,
                    fit: BoxFit.cover,
                  ),
                )),
          ),
        ),
      ),
    );
  


class ProductDetail extends StatelessWidget 
  final FeatureProduct product;

  ProductDetail(this.product);

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        title: Text("$product.productName"),
      ),
      body: Padding(
        padding: EdgeInsets.all(16.0),
        child: Text('$product.productDescription'),
      ),
    );
  

【讨论】:

以上是关于单击 Gridview 项时将数据传递到另一个屏幕的主要内容,如果未能解决你的问题,请参考以下文章

Python - 想要在它们都运行时将数据从一个脚本传递到另一个脚本

单击时如何使列表视图导航到另一个页面

在 android 中单击按钮时将列表视图中的选中项目转移到另一个列表视图

SwiftUI如何在关闭时将数据传递到上一个屏幕

iOS - 使用 xib 中的 tabBarController 将数据从一个 viewController 传递到另一个 viewController

将用户导航到 listitem 上的新屏幕单击 React native