如何使小部件的最大尺寸等于一行中的弹性值
How to make a widget maximum size be equal to the flex value in a row
我有这个小代码:
Container(
color: Colors.blue,
child: Row(
children: [
Expanded(
child: Container(
color: Colors.red,
child: const Text('Red text that can be long long long long long'),
),
),
Flexible(
child: Container(
color: Colors.green,
child: const Text('Small text'),
),
),
],
),
),
呈现为:
注意长文本是如何换行的,尽管小文本周围仍然有 space。
我希望小文本只占用所需的大小,让长文本占用其余部分。如果小文本变大,它的最大大小将是行中 Flexible
小部件的大小(在我的示例中是 Row
的一半,因为 Expanded
和 Flexible
有 flex: 1
).
如果小文本足够小,它应该看起来像:
| Red text that can be long long long long | Small text |
| long | |
如果“小”文本太长:
| Red text that can be long | Small text that is also |
| long long long long | very long |
有办法吗?
绿色可以使用ConstrainedBox:constraints: BoxConstraints.loose( Size.fromWidth(maxWidth / 2)
。
body:LayoutBuilder(
builder: (context, constraints) => Row(
children: [
Expanded(
child: Container(
color: Colors.red,
child: const Text(
'Red text that can be long long long lbe long long long lbe long long long long long'),
),
),
ConstrainedBox(
constraints: BoxConstraints.loose(
Size.fromWidth(constraints.maxWidth / 2)),
child: Container(
color: Colors.green,
child: const Text('Smalled g long th xt'),
),
),
],
),
),
Row(
children: <Widget>[
Expanded(
child:Container(
color: Colors.green,
child: const Text('Small text'),
),
),
Expanded(
child: Container(
color: Colors.red,
child: const Text('Small text'),
),
),
]
)
最后我用了Yeasin Sheikh's 所以我验证一下
但我写这篇评论是为了更加精确地说明我在调查中发现的内容。
起初,我想要一个像 Flexible
或 Expanded
(比方说 LooseFlexible
)这样的简单小部件来包装我的小部件:
View upvote and downvote totals.
I have this small code:
Container(
color: Colors.blue,
child: Row(
children: [
Expanded(
child: Container(
color: Colors.red,
child: const Text('Red text that can be long long long long long'),
),
),
LooseFlexible(
flex: 1
child: Container(
color: Colors.green,
child: const Text('Small text'),
),
),
],
),
),
但这似乎违背了 Flutter 的工作方式。
我看了一下flutterclassRenderFlex
,这是renderobjectFlex
class(一个class Row
和 Column
正在扩展)returns 在方法 createRenderObject
中。
它有一个方法_computeSizes
,在里面它通过children(一个接一个):
- 如果它没有
flex
值(“普通小部件”):
它为 child 提供了布局的无最大约束并获取其大小。
- 如果它有一个
flex
值(来自 Flexible
或 Expanded
):
它在 totalFlex
值中累积了所有 flex
中的一些值(并且 不 呈现 child)。
然后它遍历所有具有 flex
值的小部件,并将它们作为最大约束 (flex / totalFlex) * (maxConstraintOfParent - totalSizeOfNonFlexChildren)
并使用它进行布局。
所以每个child布局只有一次。
如果我的小部件 LooseFlexible
存在,并且我们有此代码:
Row(
children: [
Expanded(flex: 1),
LooseFlexible(flex: 1),
Expanded(flex: 1),
],
),
假设该行的 maxWidth
为 300
。没有non-flexchildren和totalFlex = 3
.
- 第一个
Expanded
将使用 maxWidth = 100
进行布局。因为它是一个 Expanded
,它的 width
将是 100
.
Flexible
小部件也使用 maxWidth = 100
布局。但它的大小可能是 50
(而不是 100
)。
- 现在轮到最后一个
Expanded
,如果我们想让它占据整个剩余的 space,它的大小将是 150
,这与第一个不一样Expanded
具有相同的 flex = 1
值。所以第一个 child 需要被 re-laid 出来,这不遵循 flutter 渲染方式 children only once.
我有这个小代码:
Container(
color: Colors.blue,
child: Row(
children: [
Expanded(
child: Container(
color: Colors.red,
child: const Text('Red text that can be long long long long long'),
),
),
Flexible(
child: Container(
color: Colors.green,
child: const Text('Small text'),
),
),
],
),
),
呈现为:
注意长文本是如何换行的,尽管小文本周围仍然有 space。
我希望小文本只占用所需的大小,让长文本占用其余部分。如果小文本变大,它的最大大小将是行中 Flexible
小部件的大小(在我的示例中是 Row
的一半,因为 Expanded
和 Flexible
有 flex: 1
).
如果小文本足够小,它应该看起来像:
| Red text that can be long long long long | Small text |
| long | |
如果“小”文本太长:
| Red text that can be long | Small text that is also |
| long long long long | very long |
有办法吗?
绿色可以使用ConstrainedBox:constraints: BoxConstraints.loose( Size.fromWidth(maxWidth / 2)
。
body:LayoutBuilder(
builder: (context, constraints) => Row(
children: [
Expanded(
child: Container(
color: Colors.red,
child: const Text(
'Red text that can be long long long lbe long long long lbe long long long long long'),
),
),
ConstrainedBox(
constraints: BoxConstraints.loose(
Size.fromWidth(constraints.maxWidth / 2)),
child: Container(
color: Colors.green,
child: const Text('Smalled g long th xt'),
),
),
],
),
),
Row(
children: <Widget>[
Expanded(
child:Container(
color: Colors.green,
child: const Text('Small text'),
),
),
Expanded(
child: Container(
color: Colors.red,
child: const Text('Small text'),
),
),
]
)
最后我用了Yeasin Sheikh's
但我写这篇评论是为了更加精确地说明我在调查中发现的内容。
起初,我想要一个像 Flexible
或 Expanded
(比方说 LooseFlexible
)这样的简单小部件来包装我的小部件:
View upvote and downvote totals.
I have this small code:
Container(
color: Colors.blue,
child: Row(
children: [
Expanded(
child: Container(
color: Colors.red,
child: const Text('Red text that can be long long long long long'),
),
),
LooseFlexible(
flex: 1
child: Container(
color: Colors.green,
child: const Text('Small text'),
),
),
],
),
),
但这似乎违背了 Flutter 的工作方式。
我看了一下flutterclassRenderFlex
,这是renderobjectFlex
class(一个class Row
和 Column
正在扩展)returns 在方法 createRenderObject
中。
它有一个方法_computeSizes
,在里面它通过children(一个接一个):
- 如果它没有
flex
值(“普通小部件”): 它为 child 提供了布局的无最大约束并获取其大小。 - 如果它有一个
flex
值(来自Flexible
或Expanded
): 它在totalFlex
值中累积了所有flex
中的一些值(并且 不 呈现 child)。
然后它遍历所有具有 flex
值的小部件,并将它们作为最大约束 (flex / totalFlex) * (maxConstraintOfParent - totalSizeOfNonFlexChildren)
并使用它进行布局。
所以每个child布局只有一次。
如果我的小部件 LooseFlexible
存在,并且我们有此代码:
Row(
children: [
Expanded(flex: 1),
LooseFlexible(flex: 1),
Expanded(flex: 1),
],
),
假设该行的 maxWidth
为 300
。没有non-flexchildren和totalFlex = 3
.
- 第一个
Expanded
将使用maxWidth = 100
进行布局。因为它是一个Expanded
,它的width
将是100
. Flexible
小部件也使用maxWidth = 100
布局。但它的大小可能是50
(而不是100
)。- 现在轮到最后一个
Expanded
,如果我们想让它占据整个剩余的 space,它的大小将是150
,这与第一个不一样Expanded
具有相同的flex = 1
值。所以第一个 child 需要被 re-laid 出来,这不遵循 flutter 渲染方式 children only once.