#list #flutter #dart #oop
Вопрос:
В настоящее время я учусь писать мобильные приложения в Flutter с помощью 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, описание, действующие лица, идентификатор). Теперь под инициализацией тех, кто определяет список с несколькими фильмами, у которых есть все эти атрибуты.
- Вопрос: Как можно использовать список для создания нескольких объектов списка фильмов и как я мог бы реализовать цикл (или что-то еще, как бы это было сделано) для отображения нескольких виджетов, соответствующих фильмам, которые я определил в списке «фильмы»?
- Вопрос: Является ли это вообще правильным подходом и сработает ли он вообще? Как я уже сказал, я в значительной степени начинаю с дротика и флаттера, так что мне действительно нужна ваша помощь.
Заранее спасибо 🙂
Так что большое спасибо, вы уже очень мне помогли. Теперь я хотел сделать виджет своей карты, и именно так я изменил код: 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 фактической строкой, которая должна быть вставлена туда, это работает. Еще раз большое спасибо за вашу помощь!
Ответ №1:
Я буду честен с вами, я не большой поклонник наборов и понятия не имею, почему вы решили их использовать, поэтому я изменил ваши наборы на карты, а также удалил целое число, которое у них было, потому что я не могу сказать, почему это было бы полезно. Как я уже сказал, именно так я кодирую, и я надеюсь, что вы сможете решить, хотите ли вы сохранить наборы или нет
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));
Редактировать:
Что касается вашего комментария об использовании переменной «Старые фильмы».
Если вы хотите добавить все эти виджеты в столбец, например:
return Column(
children: [
for (var movie in movies)
MovieWidget(model: MovieModel.fromJson(movie)),
],
);
Очевидно, что в приведенном выше примере, если вы хотите добавить заполнение, вам просто нужно окружить MovieWidget
его заполнением.
Комментарии:
1. Привет, большое спасибо за помощь. Я использовал наборы больше, чем карты, что привело к тому, что я не был по-настоящему уверен в использовании карт, но я вижу преимущества, которые они приносят. В принципе, у меня все еще есть вопрос. Возможно, я добавляю две переменные списка (последние две строки, которые вы мне велели добавить) или делаю что-то еще не так, но до сих пор это всегда подчеркивалось красным с этим сообщением:
The instance member 'movies' can't be accessed in an initializer. Try replacing the reference to the instance member with a different expression
Еще раз большое спасибо за помощь, и я надеюсь, что у вас будет хороший день 🙂2. Вы пытаетесь создать переменные класса виджетов и моделей? Если да, то ошибка исходит оттуда, возможное решение состоит в том, чтобы сделать их функциями получения , от
type variableName = value;
доtype get variableName => value
, такList<MovieModel> get models => movies.map((movie) => MovieModel(...));
иList<Widget> get widgets => models.map((model) => MovieWidget(model: model));
, но я не уверен, что это решит проблему.3. Поэтому я получаю несколько стрелок. Просто чтобы убедиться, что я не получу эти стрелы, потому что я сделал что-то не так… Не могли бы вы показать, как будет выглядеть код в файле? Я не уверен, что положил все туда, куда следовало. Это было бы большим подспорьем. Заранее спасибо:)
4. В итоге я внес некоторые небольшие изменения в код, чтобы он работал, но вот в чем все дело: pastebin.com/MzMq6fKR
5. Большое спасибо, что мне передать виджету, если я хочу использовать его в другом месте?