Flutter - 对齐和环绕问题
Flutter - Alignment and Wrapping issues
我正在尝试构建一个 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())
),
],
),
),
],
)
],
),
),
),
);
}
如上图所示,布局层次结构是
Row -> Image, Column -> (Row -> (Title, Rating)), Description, Text,
Text
第一期
第一个问题是我无法将评级在标题、评级行中右对齐。所以我希望标题左对齐,评级右对齐。为此,我试图给两个小部件一个弹性评级,但一旦我这样做,两个都消失了。我能想到的唯一方法是给标题一个宽度,但这是一种非常 hacky 的方法,并且会在大多数设备上中断。
第二期
我希望描述符合卡片的范围。但是,除非我为描述容器定义一个特定的宽度,否则我无法将它限制在屏幕范围内。我尝试将它封装在具有各种 flex 值的 Expanded、Flex 和 Flexible 中,但没有成功。我尝试使用文本小部件的 softWrap 属性,但还是没有成功。一旦我将文本包装在任何这些小部件中,它就会消失。在上面的代码中,我将文本包装在一个容器中,并为其设置了宽度。这行得通,但同样,它非常 hacky,在不同的设备上看起来会有所不同,而且会在一些设备上中断。
对这些问题的任何帮助都会很棒。
这里是你这两个问题的解决方案。
1) You just have to assign 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,
),
)
],
)
经过反复试验,终于如愿以偿。
我的布局是这样的:
@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)
),
],
),
),
],
),
),
],
),
),
);
}
我必须做的是将顶级行的第二个 child 设为扩展小部件。因此,正如您在代码中看到的那样,我将我的列(在图像之后)放在 Expanded.
中
之前发生的问题是 Row 有无限边界,所以让我的文本在行的列内扩展没有任何区别。
但是,当我将整个列放入展开时,它会受到屏幕宽度的限制。这就是需要做的。
我正在尝试构建一个 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())
),
],
),
),
],
)
],
),
),
),
);
}
如上图所示,布局层次结构是
Row -> Image, Column -> (Row -> (Title, Rating)), Description, Text, Text
第一期
第一个问题是我无法将评级在标题、评级行中右对齐。所以我希望标题左对齐,评级右对齐。为此,我试图给两个小部件一个弹性评级,但一旦我这样做,两个都消失了。我能想到的唯一方法是给标题一个宽度,但这是一种非常 hacky 的方法,并且会在大多数设备上中断。
第二期
我希望描述符合卡片的范围。但是,除非我为描述容器定义一个特定的宽度,否则我无法将它限制在屏幕范围内。我尝试将它封装在具有各种 flex 值的 Expanded、Flex 和 Flexible 中,但没有成功。我尝试使用文本小部件的 softWrap 属性,但还是没有成功。一旦我将文本包装在任何这些小部件中,它就会消失。在上面的代码中,我将文本包装在一个容器中,并为其设置了宽度。这行得通,但同样,它非常 hacky,在不同的设备上看起来会有所不同,而且会在一些设备上中断。
对这些问题的任何帮助都会很棒。
这里是你这两个问题的解决方案。
1) You just have to assign 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,
),
)
],
)
经过反复试验,终于如愿以偿。
我的布局是这样的:
@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)
),
],
),
),
],
),
),
],
),
),
);
}
我必须做的是将顶级行的第二个 child 设为扩展小部件。因此,正如您在代码中看到的那样,我将我的列(在图像之后)放在 Expanded.
中之前发生的问题是 Row 有无限边界,所以让我的文本在行的列内扩展没有任何区别。 但是,当我将整个列放入展开时,它会受到屏幕宽度的限制。这就是需要做的。