Флаттер - выравнивание и упаковка - PullRequest
0 голосов
/ 11 мая 2018

Я пытаюсь создать ListView, где плитки выглядят так: enter image description here

Однако я столкнулся с некоторыми проблемами здесь. Таким образом, элемент макета

@override
Widget build(BuildContext context) {
  return new GestureDetector(
    onTap: _onTap,
    child: new Card(
      elevation: 1.0,
      color: Colors.white,
      margin: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 15.0),
      child: new Container(
        child: new Row(
          mainAxisAlignment: MainAxisAlignment.start,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            new Container(
              margin: const EdgeInsets.only(right: 15.0),
              width: 100.0,
              height: 130.0,
              padding: const EdgeInsets.symmetric(
                  vertical: 10.0, horizontal: 5.0),
              decoration: new BoxDecoration(
                  shape: BoxShape.rectangle,
                  image: new DecorationImage(
                      fit: BoxFit.cover,
                      image: new NetworkImage(
                          "https://image.tmdb.org/t/p/w500" +
                              widget.movie.posterPath
                      )
                  )
              ),
            ),
            new Column(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                new Row(
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: <Widget>[
                    new Expanded(
                      flex: 0,
                      child: new Container(
                        margin: const EdgeInsets.only(
                            top: 12.0, bottom: 10.0),
                        child: new Text(widget.movie.title,
                          style: new TextStyle(
                            fontSize: 18.0,
                            color: Colors.black,
                            fontWeight: FontWeight.bold,
                          ),
                        ),
                      ),
                    ),
                    new Expanded(
                      flex: 0,
                      child: new Text(
                        widget.movie.voteAverage.toString(),
                        style: new TextStyle(
                            fontSize: 16.0,
                            fontWeight: FontWeight.bold,
                            color: Colors.grey[600]
                        ),
                      ),
                    ),
                  ],
                ),
                new Container(
                  child: new Text(widget.movie.overview,
                    softWrap: true,
                    overflow: TextOverflow.ellipsis,
                    maxLines: 3,
                  ),
                ),
                new Container(
                  margin: const EdgeInsets.only(top: 5.0),
                  child: new Row(
                    children: <Widget>[
                      new Text("Released"),
                      new Container(
                          margin: const EdgeInsets.only(left: 5.0),
                          child: new Text(widget.movie.releaseDate)
                      ),
                    ],
                  ),
                ),
                new Container(
                  margin: const EdgeInsets.only(top: 5.0),
                  child: new Row(
                    children: <Widget>[
                      new Text("Rating"),
                      new Container(
                          margin: const EdgeInsets.only(left: 5.0),
                          child: new Text(widget.movie.voteAverage.toString())
                      ),
                    ],
                  ),
                ),
              ],
            )
          ],
        ),
      ),
    ),
  );
}

Иерархия макетов, как вы можете видеть на изображении выше,

Строка -> Изображение, Колонка -> (Строка -> (Заголовок, Рейтинг)), Описание, Текст, Текст

  1. Первый выпуск

    Первая проблема заключается в том, что я не могу выровнять рейтинг вправо в строке «Название, рейтинг». Поэтому я хочу, чтобы заголовок был выровнен по левому краю, а рейтинг - по правому краю. Для этого я попытался дать гибкую оценку обоим виджетам, но как только я это сделаю, оба исчезнут. Единственный способ, которым я могу придумать, - это присвоить Title ширину, но это очень хакерский способ, и он сломается на большинстве устройств.

  2. Второй выпуск

    Я хочу, чтобы Описание вписывалось в рамки Карты. Однако, если я не определю конкретную ширину для контейнера для описания, я не смогу ограничить ее в пределах экрана. Я попытался заключить его в Expanded, Flex и Flexible с различными значениями flex, но безуспешно. Я попытался использовать свойство softWrap текстового виджета, но опять не повезло. Как только я заверну текст в любой из этих виджетов, он исчезнет. В приведенном выше коде я обернул текст в контейнер, и установить его ширину. Это работает, но, опять же, это очень хакерски, и будет выглядеть по-разному на разных устройствах, плюс сломается на некоторых.

Будет полезна любая помощь по этим вопросам.

Ответы [ 2 ]

0 голосов
/ 11 мая 2018

После долгих проб и ошибок мне наконец удалось получить то, что я хотел.

Мой макет выглядит так:

@override
  Widget build(BuildContext context) {
    return new GestureDetector(
      onTap: _onTap,
      child: new Card(
        elevation: 1.0,
        color: Colors.white,
        margin: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 14.0),
        child: new Row(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            new Container(
              margin: const EdgeInsets.only(right: 15.0),
              width: 100.0,
              height: 150.0,
              child: new Image.network(
                  "https://image.tmdb.org/t/p/w500" +
                      widget.movie.posterPath),
            ),
            new Expanded(
              child: new Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  new Row(
                    children: <Widget>[
                      new Expanded(
                        child: new Container(
                          margin: const EdgeInsets.only(
                              top: 12.0, bottom: 10.0),
                          child: new Text(widget.movie.title,
                            style: new TextStyle(
                              fontSize: 18.0,
                              color: Colors.black,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                        ),
                      ),
                      new Container(
                        margin: const EdgeInsets.only(right: 10.0),
                        child: new Text(
                          widget.movie.voteAverage.toString(),
                          style: new TextStyle(
                              fontSize: 16.0,
                              fontWeight: FontWeight.bold,
                              color: Colors.grey[600]
                          ),
                        ),
                      ),
                    ],
                  ),
                  new Container(
                    margin: const EdgeInsets.only(right: 10.0),
                    child: new Text(widget.movie.overview,
                      style: new TextStyle(
                        fontSize: 16.0,
                      ),
                      maxLines: 3,
                      overflow: TextOverflow.ellipsis,
                    ),
                  ),
                  new Container(
                    margin: const EdgeInsets.only(top: 10.0),
                    child: new Row(
                      children: <Widget>[
                        new Text("RELEASED",
                          style: new TextStyle(
                            color: Colors.grey[500],
                            fontSize: 11.0,
                          ),
                        ),
                        new Container(
                            margin: const EdgeInsets.only(left: 5.0),
                            child: new Text(widget.movie.releaseDate)
                        ),
                      ],
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

Что мне нужно было сделать, так это сделать второго потомка моей строки верхнего уровня расширенным виджетом. Итак, как вы можете видеть в коде, я поместил свой столбец (после изображения) в Расширенный.

Проблема, которая случалась раньше, заключалась в том, что строка имеет бесконечные границы, поэтому расширение текста в столбце строки не имело никакого значения. Однако, когда я поместил весь столбец в развернутый, он был ограничен шириной экрана. Вот что нужно сделать.

Окончательный вывод с приведенным выше кодом выглядит следующим образом. enter image description here

0 голосов
/ 11 мая 2018

Вот решение обеих ваших проблем.

1) Вам просто нужно назначить mainAxisAlighment.spaceBetween.

И вам будет хорошо.

Ниже приведен пример кода, который решает обе ваши проблемы.

new Column(
          children: <Widget>[
            new Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[
                new Container(
                  margin: const EdgeInsets.only(
                      top: 12.0, bottom: 10.0, left: 10.0),
                  child: new Text(
                    "Avengers: Infinity war",
                    style: new TextStyle(
                      fontSize: 18.0,
                      color: Colors.black,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                ),
                new Container(
                  margin: const EdgeInsets.all(10.0),
                  child: new Text(
                    "8.6",
                    style: new TextStyle(
                        fontSize: 16.0,
                        fontWeight: FontWeight.bold,
                        color: Colors.grey[600]),
                  ),
                )
              ],
            ),
            new Container(
              margin: const EdgeInsets.only(left: 10.0, right: 10.0),
              child: new Text(
                "Iron Man, Thor, the Hulk and the rest of the Avengers unite to battle their most powerful enemy yet -- the evil Thanos. On a mission to collect all six Infinity Stones, Thanos plans to use the artifacts to inflict his twisted will on reality.",
                softWrap: true,
                maxLines: 3,
                overflow: TextOverflow.ellipsis,
              ),
            )
          ],
        )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...