首页 > 解决方案 > 如何在颤振中调用可增长的列表

问题描述

我正在开发一个颤振的电子商务应用程序。我的数据是动态调用的。我创建了一个 Food_data 类

class Food{
  final String id;
  final String name;
  final String imagePath;
  //final String description;
  final String category;
  final double price;
  final double discount;
  final double ratings;

  Food({
    this.id,
    this.name,
    this.imagePath,
    //this.description,
    this.category,
    this.price,
    this.discount,
    this.ratings
  });


 final foods = [
    Food(
      id: "1",
      name: "Hot Cofee",
      imagePath: "assets/images/breakfast.jpeg",
      category: "1",
      price: 22.0,
      discount: 33.5,
      ratings: 99.0,
    ),
    Food(
      id: "1",
      name: "Grilled Chicken",
      imagePath: "assets/images/launch.jpeg",
      category: "2",
      price: 12.0,
      discount: 34.5,
      ratings: 69.0,
    ),
  ];

}

我需要访问下面 homescreen.dart 文件中的食物列表

//data
import 'data/food_data.dart';


class HomeScreen extends StatefulWidget {

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

class _HomeScreenState extends State<HomeScreen>{

//Assigning of foods into _foods
 List<Food> _foods = foods;

  @override
  Widget build(BuildContext context) {
    
    return Scaffold(
        body: ListView(
          padding: EdgeInsets.only(top: 50.0, left: 20.0, right: 20.0),
          children: <Widget>[
           HomeTopInfo(),
           FoodCategory(),
           SizedBox(height: 20.0),
           SearchField(),
           SizedBox(height: 20.0),
           Row(
             mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              Text("Frequently Bought Foods",
              style: TextStyle(
               fontSize: 18.0,
               fontWeight: FontWeight.bold,
              ),
              ),

我在 homescreen.dart 类中导入了 food_data.dart。我也称列表 _myFood = foods; 食物列表会将详细信息添加到 _myFood。

现在在我的颤振程序中,它看到食物没有被初始化。但我在我的 Food 课上创建了它。

标签: flutterdart

解决方案


foods在您提供的代码段中,您在类主体中创建了变量:

class Food {
    //...
    final foods = [
       Food(
         id: "1",
         name: "Hot Cofee",
         imagePath: "assets/images/breakfast.jpeg",
         category: "1",
         price: 22.0,
         discount: 33.5,
         ratings: 99.0,
       ),
       Food(
          id: "1",
          name: "Grilled Chicken",
          imagePath: "assets/images/launch.jpeg",
          category: "2",
          price: 12.0,
          discount: 34.5,
          ratings: 69.0,
       ),
    ];
}

因此,以这种方式,要访问该变量,您必须首先创建该类的一个实例:

List<Food> _foods = Food(...).foods;
// List<Food> _foods = Food.foods; // Throw an error: Getter not found 'foods'

为什么?因为,通过这种方式,我们说:当这个类被实例化时,final 字段foods必须存在。

那么,我们能做些什么来让它变得可访问呢?

事实上,有两种选择:

您可以从类主体外部声明变量,因此您可以访问它,而与实例的存在无关:

class Food{
  final String id;
  final String name;
  final String imagePath;
  //final String description;
  final String category;
  final double price;
  final double discount;
  final double ratings;

  Food({
    this.id,
    this.name,
    this.imagePath,
    //this.description,
    this.category,
    this.price,
    this.discount,
    this.ratings
  });
}

final foods = [
    Food(
      id: "1",
      name: "Hot Cofee",
      imagePath: "assets/images/breakfast.jpeg",
      category: "1",
      price: 22.0,
      discount: 33.5,
      ratings: 99.0,
    ),
    Food(
      id: "1",
      name: "Grilled Chicken",
      imagePath: "assets/images/launch.jpeg",
      category: "2",
      price: 12.0,
      discount: 34.5,
      ratings: 69.0,
    ),
];
List<Food> _foods = foods; // Works

或者,您可以将字段声明为static,这意味着该字段将被视为“类变量”而不是“对象/实例变量”(仅在创建类的实例时存在)。

    //...
    static final foods = [
       ...
    ];
}

但是,在我看来,将其声明为 并非如此static,因为foods它是“s 的示例列表Food”,而不是“类的全局唯一字段Food”。

使小部件类和小部件状态类都可以访问该变量

为了使两个类(主类和状态类)都可以访问变量,(也许)最合适的方法是在主类中声明局部变量并通过widget变量在状态类中访问它:

import 'data/food_data.dart';

class HomeScreen extends StatefulWidget {
   final List<Food> _foods = foods;

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

class _HomeScreenState extends State<HomeScreen>{
   List<Food> foods;

   // This is an option (you can do it in another way)
   @override
   void initState() {
      super.initState();
      foods = widget._foods;
   }

   //...
}

或者,如果您将变量声明为类的静态字段

List<Food> _foods = Food.foods;

而且,这里是一个使用这个变量的例子(来自_HomeScreenState类的内部):

ListView.builder(
    itemCount: widget._foods.length, //or 'foods.length'
    itemBuilder: (context, index) {
        return ListTile(
            leading: CircleAvatar(
                backgroundImage: Image.assets(widget._foods[index].imagePath),
                backgroundColor: Colors.grey, // or other color you prefer
                onBackgroundImageError: (err) { print(err); }
            ),
            title: Text(widget._foods[index].name),
            subtitle: Text(widget._foods[index].price.toString()),
        );
    }
)

推荐阅读