6

我正在尝试构建一个 ListView,其中的图块如下所示: 在此处输入图像描述

但是,我在这里面临一些问题。所以项目布局是

@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、Rating 行中将 Rating 对齐到右侧。所以我希望标题左对齐,评级右对齐。为此,我尝试为这两个小部件提供 flex 评级,但一旦我这样做,它们都会消失。我能想到的唯一方法是给标题一个宽度,但这是一种非常笨拙的方法,并且会在大多数设备上中断。

  2. 第二期

    我希望描述适合卡片的范围。但是,除非我为描述容器定义特定宽度,否则我无法将其限制在屏幕范围内。我尝试用各种 flex 值将它封装在 Expanded、Flex 和 Flexible 中,但没有运气。我尝试使用 Text 小部件的 softWrap 属性,但还是没有运气。一旦我将文本包装在任何这些小部件中,它就会消失。在上面的代码中,我将文本包装在一个容器中,并为其设置了宽度。这可行,但同样,它非常hacky,并且在不同的设备上看起来会有所不同,而且会在一些设备上中断。

在这些问题上的任何帮助都会很棒。

4

2 回答 2

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 中。

之前发生的问题是 Row 有无限的界限,所以让我的文本在一行的列中展开并没有任何区别。但是,当我将整个列放入展开时,它受到屏幕宽度的限制。这就是需要做的。

带有上述代码的最终输出如下所示。 在此处输入图像描述

于 2018-05-11T19:29:21.797 回答
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,
              ),
            )
          ],
        )
于 2018-05-11T07:34:52.223 回答