使用Flexible + IntrinsicWidth
Row(
children: [
Text('第一个text'),
IntrinsicWidth(
child: ConstrainedBox(
constraints: BoxConstraints(maxWidth: 200),
child: Text(
'中间的text可能很长也可能很短',
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
),
),
Text('第三个text'),
],
)
使用LayoutBuilder + 自定义计算
LayoutBuilder(
builder: (context, constraints) {
final firstText = '第一个text';
final middleText = '中间的text可能很长也可能很短';
final thirdText = '第三个text';
final textPainter = TextPainter(
text: TextSpan(text: middleText),
textDirection: TextDirection.ltr,
);
textPainter.layout();
final middleTextWidth = textPainter.width;
final maxWidth = 200.0;
final actualWidth = middleTextWidth < maxWidth ? middleTextWidth : maxWidth;
return Row(
children: [
Text(firstText),
SizedBox(
width: actualWidth,
child: Text(
middleText,
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
),
Text(thirdText),
],
);
},
)
使用CustomMultiChildLayout
CustomMultiChildLayout(
delegate: _ThreeTextLayoutDelegate(maxWidth: 200),
children: [
LayoutId(
id: 'first',
child: Text('第一个text'),
),
LayoutId(
id: 'middle',
child: Text(
'中间的text可能很长也可能很短',
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
),
LayoutId(
id: 'third',
child: Text('第三个text'),
),
],
)
class _ThreeTextLayoutDelegate extends MultiChildLayoutDelegate {
final double maxWidth;
_ThreeTextLayoutDelegate({required this.maxWidth});
@override
void performLayout(Size size) {
final firstSize = layoutChild('first', BoxConstraints.loose(size));
final thirdSize = layoutChild('third', BoxConstraints.loose(size));
final availableWidth = size.width - firstSize.width - thirdSize.width;
final middleConstraints = BoxConstraints(
maxWidth: availableWidth.clamp(0, maxWidth),
minWidth: 0,
);
final middleSize = layoutChild('middle', middleConstraints);
positionChild('first', Offset.zero);
positionChild('middle', Offset(firstSize.width, 0));
positionChild('third', Offset(firstSize.width + middleSize.width, 0));
}
@override
bool shouldRelayout(covariant MultiChildLayoutDelegate oldDelegate) => false;
}
使用StatefulWidget + 动态计算
class AdaptiveTextRow extends StatefulWidget {
final String firstText;
final String middleText;
final String thirdText;
final double maxMiddleWidth;
const AdaptiveTextRow({
super.key,
required this.firstText,
required this.middleText,
required this.thirdText,
this.maxMiddleWidth = 200,
});
@override
State<AdaptiveTextRow> createState() => _AdaptiveTextRowState();
}
class _AdaptiveTextRowState extends State<AdaptiveTextRow> {
double? middleTextWidth;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
_calculateMiddleTextWidth();
});
}
void _calculateMiddleTextWidth() {
final textPainter = TextPainter(
text: TextSpan(text: widget.middleText),
textDirection: TextDirection.ltr,
);
textPainter.layout();
setState(() {
middleTextWidth = textPainter.width;
});
}
@override
Widget build(BuildContext context) {
if (middleTextWidth == null) {
return Row(
children: [
Text(widget.firstText),
Flexible(
child: Text(
widget.middleText,
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
),
Text(widget.thirdText),
],
);
}
final actualWidth = middleTextWidth! < widget.maxMiddleWidth
? middleTextWidth!
: widget.maxMiddleWidth;
return Row(
children: [
Text(widget.firstText),
SizedBox(
width: actualWidth,
child: Text(
widget.middleText,
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
),
Text(widget.thirdText),
],
);
}
}
AdaptiveTextRow(
firstText: '第一个text',
middleText: '中间的text可能很长也可能很短',
thirdText: '第三个text',
maxMiddleWidth: 200,
)