flutterdartoopmapsflutter-assetimage

Adding Images to card and text


Hi I've been building this app and I came across a problem that I dont know how to solve. I want to have a Row of Card Widgets, that all display some info I provided beforehand. This is basically how I wanted to do it:

``
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(25.0),
            ),
            elevation: 10.0,
            margin: const EdgeInsets.all(10.0),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Container(
                  height: 200.0,
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(10.0),
                    image: DecorationImage(
                        image: AssetImage(model.bannerPath), fit: BoxFit.cover),
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.all(10.0),
                  child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text(
                          model.title,
                          maxLines: 1,
                          overflow: TextOverflow.ellipsis,
                          style: const TextStyle(
                              color: Colors.redAccent,
                              fontWeight: FontWeight.w800),
                        ),
                        Text(
                          model.description,
                          softWrap: true,
                          maxLines: 4,
                          overflow: TextOverflow.ellipsis,
                          style: const TextStyle(fontWeight: FontWeight.w500),
                        ),
                      ]),
                ),
              ],
            )));
  }
}``
``
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':
        '"21" is the fact-based story about six MIT students who were trained to become experts in card counting and subsequently took Vegas casinos for millions in winnings.',
    'actors': ['Kate Bosworth', 'Jim Slurgess', 'Kevvin Spacey']
  },
  {
    'title': 'Endless Love',
    'bannerPath': 'assets/images/endless_love_movie.jpeg',
    'description':
        'The story of a privileged girl and a charismatic boy whose instant desire sparks a love affair made only more reckless by parents trying to keep them apart',
    'actors': ['Alex Pettyfer', 'Gabrielle Wilde', 'Bruce Greenwood']
  },
  {
    'title': 'Kevin allein zuhaus',
    'bannerPath': 'assets/images/kevin_allein_zuhaus_movie.jpeg',
    'description':
        'Dieses Jahr fliegt die gesamte McAllister-Familie nach Frankreich, um dort gemeinsam Weihnachten zu feiern. Leider haben sie bei ihrer hektischen Abreise ihren achtjährigen Sprößling Kevin zu Hause vergessen. Dieser genießt natürlich seine neugewonnene Freiheit.',
    'actors': ['Macaulay Culkin', 'Joe Pesci', 'John Heard']
  },
  {
    'title': 'Little Woman',
    'bannerPath': 'assets/images/little_woman_movie.jpeg',
    'description':
        'rThe story follows the lives of the four March sisters—Meg, Jo, Beth, and Amy—and details their passage from childhood to womanhood. Loosely based on the lives of the author and her three sisters, it is classified as an autobiographical or semi-autobiographical novel.',
    'actors': ['Saorise Ronan', 'Timothée Chalamet', 'Florence Pugh']
  },
  {
    'title': 'Liebe braucht keine Ferien',
    'bannerPath': 'assets/images/love_movie.jpeg',
    'description':
        'Amanda ist enttäuscht von der Liebe und will nichts wie weg aus Los Angeles. Genauso geht es Iris in England. Über das Internet vereinbaren die beiden Frauen einen Häusertausch. In England trifft Amanda schon bald auf Iris attraktiven Bruder, und Iris lernt einen Arbeitskollegen von Amanda kennen.',
    'actors': [
      'Jude Law',
      'Cameron Diaz',
      'Kate Winslet',
    ]
  },
  {
    'title': 'Marvel Movies',
    'bannerPath': 'assets/images/marvel_movie.jpeg',
    'description':
        'The Marvel Cinematic Universe (MCU) is an American media franchise and shared universe centered on a series of superhero films produced by Marvel Studios.',
    'actors': [
      'Chris Evans',
      'Robert Downey Jr.',
      'Chris Hemsworth',
      'Scarlett Johansson',
    ],
  },
  {
    'title': 'Oceans 12',
    'bannerPath': 'assets/images/oceans_12_movie.jpeg',
    'description':
        'Set three years after "Ocean\'s 11," this sequel shows us Danny Ocean gathering up his complete gang of con artists and thieves from the first film in New York City before they all jet off to Amsterdam, Rome, and Paris to pull off three seperate heists.',
    'actors': [
      'George Clooney',
      'Julia Roberts',
      'Catherine Zeta-Jones',
      'Brad Pitt',
    ]
  },
  {
    'title': 'assets/images/star_movie.jpeg',
    'bannerPath': 'assets/images/star_movie.jpeg',
    'description':
        'Der in die Jahre gekommene Rockstar Jackson Maine entdeckt die talentierte Sängerin Ally und verliebt sich in sie. Ally hätte ihren großen Traum von einer Musikkarriere fast aufgegeben. Jackson fördert sie und nimmt sie schließlich sogar mit auf seine Tournee.',
    'actors': [
      'Lady Gaga',
      'Bradley Cooper',
      'Sam Elliot',
    ]
  },
  {
    'title': 'Die Entdeckung der Unendlichkeit',
    'bannerPath': 'assets/images/stephen_hawking_movie.jpeg',
    'description':
        'Bereits während seines Studiums in Cambridge erkrankt der geniale Physiker Stephen Hawking an der degenerativen Nervenkrankheit ALS. Nur die Liebe zu der Romanistikstudentin Jane Wilde gibt ihm die Kraft, nicht in Depressionen zu versinken und seine Forschungen voranzutreiben. ',
    'actors': [
      'Eddie Radmyne',
      'Felicity Jones',
      'Jane Hawking',
      'Charlie Cox',
    ]
  },
  {
    'title': 'Frühstück bei Tiffany',
    'bannerPath': 'assets/images/tiffany_movie.jpeg',
    'description':
        'Holly Golightly sucht einen reichen Ehemann, hat gutbetuchte Freunde, eine namenlose Katze und einen mittellosen Begleiter, der ihr immer aus der Patsche hilft. Ihr Traum: eine Wohnung so schön wie bei Tiffanys. Doch dann fordert der Exmann alte Rechte ein, die Polizei stellt unbequeme Fragen, und der Heiratskandidat aus Brasilien verrschwindet.',
    'actors': [
      'Audrey Hepburn',
      'George Peppard',
      'Patricia Neal',
    ],
  },
];

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

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          const Padding(
            padding: EdgeInsets.only(bottom: 20.0),
            child: HeaderWidget(),
          ),
          const Padding(
            padding: EdgeInsets.only(right: 20.0, left: 20.0),
            child: FilmstoWatch(),
          ),
          Padding(
            padding: const 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)),
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }
}
``

The output on the emulator looks like this: https://drive.google.com/file/d/1nDah5cqgBLNBS69n4sJ5Xi8rtEmgWSOJ/view?usp=sharing

  1. How do I get the text to appear in several lines (descriptiontext) not in one?
  2. Why isn't my AssetImage showing up?

Thanks for the help in advance :)


Solution

  • You can do so by restricting the Card width by SizedBox or Container and then using the maxLines and overflow as you had used.

    See the changes below in your MovieWidget

      @override
      Widget build(BuildContext context) {
        return SizedBox(
            width: 300,
            height: 305,
            child: Card(
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(25.0),
                ),
                elevation: 10.0,
                margin: const EdgeInsets.all(10.0),
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Container(
                      height: 200.0,
                      decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(10.0),
                        image: DecorationImage(
                            image: AssetImage(model.bannerPath), fit: BoxFit.cover),
                      ),
                    ),
                    Padding(
                      padding: const EdgeInsets.all(10.0),
                      child: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            Text(
                              model.title,
                              maxLines: 1,
                              overflow: TextOverflow.ellipsis,
                              style: const TextStyle(
                                  color: Colors.redAccent,
                                  fontWeight: FontWeight.w800),
                            ),
                            Text(
                              model.description,
                              maxLines: 3,
                              overflow: TextOverflow.ellipsis,
                              style: const TextStyle(fontWeight: FontWeight.w500),
                            ),
                          ]),
                    ),
                  ],
                )));
      }