【问题标题】:Making multiple Widgets from one list从一个列表制作多个小部件
【发布时间】:2021-12-14 20:55:32
【问题描述】:

我目前正在学习使用 Dart 在 Flutter 中编写移动应用程序,最近我想尝试构建一个应用程序,您可以在其中保留您想观看的电影并获取有关它们的一些基本信息。现在这只是为了我,训练理解颤振的基本概念,我想问如何从一个列表中制作多个小部件。我会向您展示我的代码,然后再详细说明。

import 'package:flutter/material.dart';

class MovieList {
  String name;
  String url;
  String description;
  String actors;
  int id;

  MovieList(this.name, this.url, this.description, this.actors, this.id);

  var movies = [
    {
      "21",
      "assets/images/21_movie.jpeg",
      "randomDescriptionfor21",
      "idkwhichactors.1",
      1
    },
    {
      "Dirty Dancing",
      "assets/images/dirty_dancing_movie.jpeg",
      "randomDescriptionforDirtyDancing",
      "idkwhichactors.2",
      2
    },
    {
      "Endless love",
      "assets/images/endless_love_movie.jpeg",
      "randomDescriptionforEndlesslove",
      "idkwhichactors.3",
      3
    },
    {
      "Gut gegen Nordwind",
      "assets/images/gut_gegen_nordwind_movie.jpeg",
      "randomDescriptionforNordwind",
      "idkwhichactors.4",
      4
    },
    {
      "Illuminati",
      "assets/images/illuminati_movie.jpeg",
      "randomDescriptionforIlluminati",
      "idkwhichactors.5",
      5
    },
    {
      "Bridget Jones",
      "assets/images/jones_movie.jpeg",
      "randomDescriptionforBridgetJones",
      "idkwhichactors.6",
      6
    },
    {
      "Kevin allein Zuhaus",
      "assets/images/kevin_allein_zuhaus_movie.jpeg",
      "randomDescriptionforKevin",
      "idkwhichactors.7",
      7
    },
    {
      "Little Woman",
      "assets/images/little_woman_movie.jpeg",
      "randomDescriptionforLittleWoman",
      "idkwhichactors.8",
      8
    },
    {
      "Liebe braucht keine Ferien",
      "assets/images/love_movie.jpeg",
      "randomDescriptionforLiebeundFerien",
      "idkwhichactors.9",
      9
    },
    {
      "Marvel-Filme",
      "assets/images/marvel_movie.jpeg",
      "randomDescriptionforMarvel",
      "idkwhichactors.10",
      10
    },
    {
      "Oceans 12",
      "assets/images/oceans_12_movie.jpeg",
      "randomDescriptionforOceans12",
      "idkwhichactors.11",
      11
    },
    {
      "Pirates of the Carribean",
      "assets/images/pirates_carribean_movie.jpeg",
      "randomDescriptionforPiraten",
      "idkwhichactors.12",
      12
    },
    {
      "Romeo und Julia",
      "assets/images/romeo_and_julia_movie.jpeg",
      "randomDescriptionforRomeoxJulia",
      "idkwhichactors.13",
      13
    },
    {
      "A star is born",
      "assets/images/star_movie.jpeg",
      "randomDescriptionforStar",
      "idkwhichactors.14",
      14
    },
    {
      "Die Entdeckung der Unendlichkeit",
      "assets/images/stephen_hawking_movie.jpeg",
      "randomDescriptionforStephen",
      "idkwhichactors.15",
      15
    },
    {
      "Frühstück bei Tiffany",
      "assets/images/tiffany_movie.jpeg",
      "randomDescriptionforTIffany",
      "idkwhichactors.16",
      16
    }
  ];
}

如您所见,我定义了一个类 MovieList,我在其中定义了某些变量(名称、url、描述、演员、id)。现在在那些我定义一个包含多部电影的列表的初始化下,它具有所有这些属性。

  1. 问题:如何使用列表来创建 MovieList 的多个对象,我如何实现一个循环(或者其他 idk 如何完成)来显示多个小部件,匹配我在“电影”列表中定义的电影?

  2. 问题:这甚至是正确的方法吗?甚至会奏效吗?就像我说的,我几乎是从飞镖和颤振开始的,所以我真的需要你的帮助。

提前致谢:)

非常感谢你真的帮了我很多。现在我想做我的卡片小部件,这基本上就是我改变代码的方式: 1:

``
import 'package:flutter/material.dart';
import './header.dart';
import './image_widget.dart';
import './movies_to_watch.dart';

var movies = [
  {
    'title': '21',
    'bannerPath': 'assets/images/21_movie.jpeg',
    'description': 'randomDescriptionforPirates',
    'actors': [
      'some actor',
    ]
  },
  {
    'title': 'Dirty Dancing',
    'bannerPath': 'assets/images/dirty_dancing_movie.jpeg',
    'description': 'randomDescriptionforPirates',
    'actors': [
      'some actor',
    ]
  },
  {
    'title': 'Endless Love',
    'bannerPath': 'assets/images/endless_love_movie.jpeg',
    'description': 'randomDescriptionforPirates',
    'actors': [
      'some actor',
    ]
  },
  {
    'title': 'Gut gegen Nordwind',
    'bannerPath': 'assets/images/gut_gegen_nordwind_movie.jpeg',
    'description': 'randomDescriptionforPirates',
    'actors': [
      'some actor',
    ]
  },
  {
    'title': 'Illuminati',
    'bannerPath': 'assets/images/illuminati_movie.jpeg',
    'description': 'randomDescriptionforPirates',
    'actors': [
      'some actor',
    ]
  },
  {
    'title': 'Bridget Jones',
    'bannerPath': 'assets/images/jones_movie.jpeg',
    'description': 'randomDescriptionforPirates',
    'actors': [
      'some actor',
    ]
  },
  {
    'title': 'Kevin allein zuhaus',
    'bannerPath': 'assets/images/kevin_allein_zuhaus_movie.jpeg',
    'description': 'randomDescriptionforPirates',
    'actors': [
      'some actor',
    ],
  },
];

class Body extends StatelessWidget {
  const Body({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Padding(
            padding: EdgeInsets.only(bottom: 20.0),
            child: HeaderWidget(),
          ),
          Padding(
            padding: EdgeInsets.only(right: 20.0, left: 20.0),
            child: FilmstoWatch(),
          ),
          Padding(
            padding: EdgeInsets.only(right: 20.0, left: 20.0),
            child: SingleChildScrollView(
              scrollDirection: Axis.horizontal,
              child: Row(
                children: [
                  for (var movie in movies)
                    MovieWidget(model: MovieModel.fromJson(movie)),
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }
}
``

和2:

``
import 'package:flutter/material.dart';

class MyClass {
  // here I am generating fake movies but you should use the data that you already have
  List<Map<String, dynamic>> movies = List.generate(
      15,
      (index) => {
            'title': 'fake title $index',
            'actors': ['fake actor $index'],
            'bannerPath': 'some/fake/path/$index',
            'description': 'some fake description $index',
          });

  List<MovieModel> get models =>
      movies.map((movie) => MovieModel.fromJson(movie)).toList();

  List<Widget> get widgets =>
      models.map((model) => MovieWidget(model: model)).toList();
}

class MovieModel {
  MovieModel({
    required this.title,
    required this.actors,
    required this.bannerPath,
    required this.description,
  });

  factory MovieModel.fromJson(Map<String, dynamic> json) {
    return MovieModel(
      title: json['title'],
      actors: json['actors'],
      bannerPath: json['bannerPath'],
      description: json['description'],
    );
  }

  String title;
  String bannerPath;
  String description;
  List<String> actors;
}

class MovieWidget extends StatelessWidget {
  const MovieWidget(
      {required this.model}); // if you decide to not make a model class, you would pass each value individually

  final MovieModel model;

  @override
  Widget build(BuildContext context) {
    // obviously this can be any widget you want
    return SingleChildScrollView(
      child: Card(
        shape:
            RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)),
        elevation: 10.0,
        margin: const EdgeInsets.all(10.0),
        child: Column(
          children: [
            Text(model.title),
            Container(
              height: 200,
              decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(10.0),
                image: DecorationImage(
                  image: AssetImage(model.bannerPath),
                ),
              ),
            ),
            Text(model.description),
            if (model.actors.isNotEmpty) Text(model.actors.first),
          ],
        ),
      ),
    );
  }
}
``

如果我运行它,我会抛出这个错误:

https://drive.google.com/file/d/1zbmsOq3lQIPUIZ92mvrg4sCcT21W8cc4/view?usp=sharing

当我用应该插入的实际字符串替换 model.bannerPath 时,它可以工作。再次感谢您的帮助!

【问题讨论】:

    标签: list flutter dart oop


    【解决方案1】:

    老实说,我不是套装的忠实粉丝,也不知道你为什么决定使用它们,所以我把你的套装改成了地图,我还删除了它们的整数,因为我可以' t 告诉它为什么有用。正如我所说,这就是我编码的方式,我希望你能决定是否要保留这些集合

    var movies = [
      ...
      {
        'title': 'Pirates of the Carribean',
        'banner': 'assets/images/pirates_carribean_movie.jpeg',
        'description': 'randomDescriptionforPiraten',
        'actors': ['some actor'],
      },
      ...
    ];
    

    我还建议您创建一个 MovieModel 类,该类可以以类型安全的方式存储这些值

    class MovieModel {
      String title;
      String bannerPath;
      String description;
      List<String> actors;
    }
    

    那么你应该制作一些可以显示你想要的信息的小部件

    class MovieWidget extends StatelessWidget {
      MovieWidget({required this.model}); // if you decide to not make a model class, you would pass each value individually
    
      final MovieModel model;
    
      @override
      Widget build(BuildContext context) {
        // obviously this can be any widget you want
        return Column(
          children: [
            Text(model.title),
            Text(model.banner),
            Text(model.description),
            Text(model.actors.first),
          ],
        );
      }
    }
    

    最后要将你的电影列表变成一个小部件列表,首先你需要把它变成一个模型列表

    final List<MovieModel> models = movies.map((movie) => MovieModel(title: movie['title'], banner: movie['banner'], description: movie['description'], actors: movie['actors']));
    

    然后你可以对小部件做同样的事情:

    List<Widget> widgets = models.map((model) => MovieWidget(model: model));
    

    编辑:

    关于您对使用 old movies 变量的评论。

    例如,如果您想将所有这些小部件添加到列中:

    return Column(
      children: [
        for (var movie in movies)
          MovieWidget(model: MovieModel.fromJson(movie)),
      ],
    );
    

    显然在上面的例子中,如果你想添加填充,你只需要用填充包围MovieWidget

    【讨论】:

    • 您好,非常感谢您的帮助。我一直在使用集合而不是地图,这导致我对使用地图并不是很安全,但我看到了它们带来的优势。基本上我还有一个问题。也许我添加了两个列表变量(你告诉我添加的最后两行)或者我做错了其他事情,但到目前为止,这条消息总是用红色下划线:The instance member 'movies' can't be accessed in an initializer. Try replacing the reference to the instance member with a different expression 再次感谢您的帮助,我希望你有美好的一天:)
    • 您是否正在尝试制作小部件和模型类变量?如果是,错误来自那里,一个可能的解决方案是让它们成为 getter 函数,从 type variableName = value;type get variableName =&gt; value,所以 List&lt;MovieModel&gt; get models =&gt; movies.map((movie) =&gt; MovieModel(...));List&lt;Widget&gt; get widgets =&gt; models.map((model) =&gt; MovieWidget(model: model));,但我不确定这会解决问题。
    • 所以我得到了多个箭头。只是为了确保我没有得到那些箭头,因为我做错了......你能展示一下代码在文件中的样子吗?我不确定我把所有东西都放在了我应该拥有的地方。这将是一个很大的帮助。在此先感谢:)
    • 我确实对代码做了一些细微的改动,为了让它工作,这里就是全部:pastebin.com/MzMq6fKR
    • 非常感谢,如果我想在不同的地方使用它,我应该向小部件传递什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-11
    • 2020-11-03
    • 2021-03-01
    • 1970-01-01
    • 2020-05-10
    相关资源
    最近更新 更多