在我的布局中,我有两个连续的小部件,一个文本和一个图标。
如下图,假设*代表图标,用“-”代表行:
----------------------------
Text *
----------------------------
如何使文本在整行居中,图标在右端?
您需要注意的主要事情是,如果您不想使用
Stack
,您应该在左侧和右侧提供相同的宽度消耗小部件。
我会用
Expanded
和 Padding
来做到这一点
Row(
children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.only(left: 32.0),
child: Text(
"Text",
textAlign: TextAlign.center,
),
),
),
Icon(Icons.add, size: 32.0,)
],
)
或与
Row
的 mainAxisAlignment
和 SizedBox
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
const SizedBox(width: 32.0),
Text("Text"),
Icon(Icons.add, size: 32.0)
],
)
或在左侧使用
Expanded
和 SizedBox
而不是填充:)。左侧的填充或额外容器是为了使 textAlign 能够真正将行中的文本居中,同时考虑到图标占用的空间。
我发现有必要使用
Stack
来让文本真正居中:
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Stack(
alignment: Alignment.center,
children: [
Align(
alignment: Alignment.center,
child: Text('Text'),
),
Align(
alignment: Alignment.centerRight,
child: Text('*'),
)
],
),
],
);
出于灵活性原因,我建议使用扩展小部件:
Row(
children: [
Expanded(flex: 1, child: Container()),
Expanded(
flex: 8,
child: Text('Your Text',
textAlign: TextAlign.center,
),
),
Expanded(flex: 1, child: IconButton(...))
],
)
对于我的情况,我通过调整
flex
小部件的 Spacer
属性解决了居中问题 -
Row(children: [
Spacer(flex: 3),//3 was for my case, It might be changed for your widgets
Text('Center'),
Spacer(flex: 1),//1 was also for my case, It might be changed on for your widgets
Text("*")]);
在开始处添加另一个图标并将不透明度设置为零。
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
CloseButton(
onPressed: () => Navigator.of(context).pop(),
),
Text('text',),
Opacity(
opacity: 0,
child: Icon(Icons.close),
),
],
)
我想要这个,其中有3个项目
Row
第一个和第二个位于该Row
的顶部,而最后一个Icon
垂直位于该行的中心。
我的方法是使用 flutter 的 IntrinsicHeight
小部件提供程序
注意:此解决方案中没有给出任何静态高度
IntrinsicHeight(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
alignment: Alignment.topLeft,
child: Icon(
Icons.offline_bolt_sharp,
color: AppColors.secondary,
),
),
hSpacing(times: .5),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
RichText(
text: TextSpan(
text: '',
style: TextStyle(),
children: <TextSpan>[
TextSpan(
text: "Free Delivery ",
style: TextStyle(
fontSize: 12,
color: AppColors.secondary,
fontWeight: FontWeight.bold,
),
recognizer: TapGestureRecognizer()
..onTap = () {}),
TextSpan(
text: "Tomorrow 5 Aug",
style: TextStyle(
fontSize: 12,
color: AppColors.secondary,
),
recognizer: TapGestureRecognizer()
..onTap = () {},
)
],
),
),
vSpacing(times: .5),
Text(
"On minimum spend of Rs ${commaNumber(3000)}",
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: AppColors.secondary,
),
),
],
),
),
Center(
child: Container(
child: Icon(
Icons.arrow_forward_ios_outlined,
size: 20,
color: AppColors.secondary,
),
),
),
],
),
))
通过这种方式,您可以将
Row
的所有元素拉伸到相等的高度,然后根据需要通过 alignment
属性进行定位。
您始终可以使用具有两个子项的堆栈,其中一个作为其自己的行,并具有扩展以将元素推到墙上,另一个作为具有所需中心小部件的中心项目。例如:
Stack(
children: [
Row(
children: [
leftWidgetHere,
Expanded(
child: Container(),
),
rightWidgetHere,
],
),
Center(
child: centerWidgetHere,
),
],
);
作为一个有用的组件类:
class CenteredRow extends StatelessWidget {
const CenteredRow({Key? key, required this.left, required this.center, required this.right}) : super(key: key);
final Widget left;
final Widget center;
final Widget right;
@override
Widget build(BuildContext context) {
return Stack(
children: [
Row(
children: [
left,
Expanded(
child: Container(),
),
right,
],
),
Center(
child: center,
),
],
);
}
}
这对我来说没有堆栈也有效。但事实恰恰相反。 “文本”向左“*”向中心:
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: Text("text",
style: Theme.of(context).textTheme.caption),
),
Text("*"),
Spacer(),
],
)