Flutter - 对齐和包装问题

6
我正在尝试构建一个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. 第一个问题

    我无法将评分对齐到标题和评分行的右侧。因此,我想让标题左对齐,评分右对齐。为此,我尝试给两个部件都设置flex rating,但是一旦我这样做,两个部件都会消失。我唯一能想到的方法是给标题设置宽度,但这是非常hacky的方式,在大多数设备上都会出现问题。

  2. 第二个问题

    我希望描述能够适应卡片范围。但是,除非我为描述容器定义特定的宽度,否则我无法将其限制在屏幕范围内。我尝试使用Expanded、Flex和Flexible将其包裹,并使用各种flex值,但没有成功。我尝试使用Text部件的softWrap属性,但仍然没有成功。一旦我将文本包装在任何这些部件中,它就会消失。在上面的代码中,我将文本包装在一个容器中,并为其设置了一个宽度。这可以工作,但再次强调,它是非常hacky的方式,在不同设备上会显示出不同效果,并且可能会出现问题。

任何有关这些问题的帮助都将是极好的。

3个回答

9
在经历了许多试错之后,我终于成功得到了我想要的东西。
我的布局是这样的:
@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)
                        ),
                      ],
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

我需要做的是将顶级行的第二个子项设置为Expanded小部件。因此,正如您在代码中看到的那样,在图像后面,我将我的列放在了一个Expanded中。
之前出现的问题是Row具有无限边界,因此使我的文本在行的列内展开对其没有任何影响。但是,当我将整个列放入一个扩展中时,它受到屏幕宽度的限制。这就是需要做的事情。
使用上述代码的最终输出如下所示。 enter image description here

0

这里是你两个问题的解决方案。

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,
              ),
            )
          ],
        )

不行,这一点也没有帮助。它使标题和评分消失了,描述仍然超出了边界。我尝试了你的代码,用你的列替换我的列-没有运气。 - Rachit
我开始找出问题所在了。问题是因为我把一个列放在了一行里面。如果我把一行放在另一行里面,你的代码就能正常工作。只有在我特定的情况下,即将一个列作为第一个元素放在一行里,并且该列包含一个图片时,这段代码才不能正常工作。 - Rachit
2
非常感谢你,伙计。你的答案实际上对我没用,但它确实让我朝着正确的方向思考了。当我意识到它在没有顶行的情况下也可以工作时,我就知道解决方案了。 - Rachit

0
只需将Wrap小部件包裹在Expanded小部件中,它就应该可以正常工作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接