Flutter:行横轴展开
Flutter: row cross axis expand
有什么方法可以为特定小部件指定行中最高小部件的高度?我不想拉伸横轴上的行。我只希望所有小部件都具有最高小部件的高度。
好的!只需将您的行包装成 IntrinsicHeight
IntrinsicHeight(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[],
),
);
有很多事情需要考虑。
Parent 行约束
IntrinsicHeight
只能工作 if "unlimited height is available". Conversely, if the parent of the Row
is constrained, it would not work DartPad.
- 如果您想做的是扩展小部件的高度以匹配 parent,只需执行以下操作:
Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
...
)
它将使所有小部件具有相同的高度,即使您将行的 children 高度设置为不相等。它会忽略 children 的高度,并且不会使其他小部件与最高的小部件相同。
Parent 行不受约束
- 如果您事先知道最高小部件的高度,只需使用
SizedBox
. 将 Row
的 parent 约束为该高度
- 如果不是,但您知道纵横比,请使用
AspectRatio
,它是一个更便宜的小部件。
AspectRatio(
aspectRatio: 2, // try diff numbers
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
)
- 如果您仍然不知道其中的任何内容(这种情况很少见),可以使用其他一些选项来手动实现布局
LayoutBuilder
或创建一个新的小部件。
- If none of that work use
IntrinsicHeight
as parent of Row 作为最后的手段,因为它应该是一个昂贵的小部件。您可以尝试测量性能(不科学,因为您需要一个真正的物理设备):
main() async {
testWidgets('test', (WidgetTester tester) async {
final Stopwatch timer = new Stopwatch()..start();
for (int index = 0; index < 1000; index += 1) {
await tester.pumpWidget( MyApp());
}
timer.stop();
debugPrint('Time taken: ${timer.elapsedMilliseconds}ms');
});
}
总结
您不太可能需要将同级小部件的高度与高度未知的单个小部件匹配。如果确实如此,则必须首先像 或间接地 IntrinsicHeight
.
一样呈现和通知小部件
编辑
方案6:如果你知道宽度,你可以使用Stack。
Container(
color: Colors.grey,
child: Stack(
children: <Widget>[
Container(child: Text("T", style: TextStyle(fontSize: 90),),color: Colors.green, width: 200,),
Positioned.fill(left: 100,child: Container(child: Text("TTTTT", style: TextStyle(fontSize: 20),),color: Colors.blue)),
],
),
),
选项 7:如果您想使用 ValueNotifier
ValueListenableBuilder
GlobalKey
.
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
GlobalKey _rowKey = GlobalKey();
final ValueNotifier<double> _rowHeight = ValueNotifier<double>(-1);
@override
void initState() {
super.initState();
WidgetsBinding.instance!.addPostFrameCallback(
(_) => _rowHeight.value = _rowKey.currentContext!.size!.height);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
color: Colors.grey,
child: ValueListenableBuilder<double>(
valueListenable: _rowHeight,
builder: (_, __, ___) => Row(
key: _rowKey,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
child: Text(
"T",
style: TextStyle(fontSize: 90),
),
color: Colors.green,
width: 200,
),
Container(
height: (_rowHeight.value<0)? null : _rowHeight.value,
child: Container(
child: Text(
"TTTTT",
style: TextStyle(fontSize: 20),
),
color: Colors.blue)),
],
),
),
),
);
}
}
有什么方法可以为特定小部件指定行中最高小部件的高度?我不想拉伸横轴上的行。我只希望所有小部件都具有最高小部件的高度。
好的!只需将您的行包装成 IntrinsicHeight
IntrinsicHeight(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[],
),
);
有很多事情需要考虑。
Parent 行约束
IntrinsicHeight
只能工作 if "unlimited height is available". Conversely, if the parent of the Row
is constrained, it would not work DartPad.
- 如果您想做的是扩展小部件的高度以匹配 parent,只需执行以下操作:
Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
...
)
它将使所有小部件具有相同的高度,即使您将行的 children 高度设置为不相等。它会忽略 children 的高度,并且不会使其他小部件与最高的小部件相同。
Parent 行不受约束
- 如果您事先知道最高小部件的高度,只需使用
SizedBox
. 将 - 如果不是,但您知道纵横比,请使用
AspectRatio
,它是一个更便宜的小部件。
Row
的 parent 约束为该高度
AspectRatio(
aspectRatio: 2, // try diff numbers
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
)
- 如果您仍然不知道其中的任何内容(这种情况很少见),可以使用其他一些选项来手动实现布局
LayoutBuilder
或创建一个新的小部件。 - If none of that work use
IntrinsicHeight
as parent of Row 作为最后的手段,因为它应该是一个昂贵的小部件。您可以尝试测量性能(不科学,因为您需要一个真正的物理设备):
main() async {
testWidgets('test', (WidgetTester tester) async {
final Stopwatch timer = new Stopwatch()..start();
for (int index = 0; index < 1000; index += 1) {
await tester.pumpWidget( MyApp());
}
timer.stop();
debugPrint('Time taken: ${timer.elapsedMilliseconds}ms');
});
}
总结
您不太可能需要将同级小部件的高度与高度未知的单个小部件匹配。如果确实如此,则必须首先像 IntrinsicHeight
.
编辑
方案6:如果你知道宽度,你可以使用Stack。
Container(
color: Colors.grey,
child: Stack(
children: <Widget>[
Container(child: Text("T", style: TextStyle(fontSize: 90),),color: Colors.green, width: 200,),
Positioned.fill(left: 100,child: Container(child: Text("TTTTT", style: TextStyle(fontSize: 20),),color: Colors.blue)),
],
),
),
选项 7:如果您想使用 ValueNotifier
ValueListenableBuilder
GlobalKey
.
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
GlobalKey _rowKey = GlobalKey();
final ValueNotifier<double> _rowHeight = ValueNotifier<double>(-1);
@override
void initState() {
super.initState();
WidgetsBinding.instance!.addPostFrameCallback(
(_) => _rowHeight.value = _rowKey.currentContext!.size!.height);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
color: Colors.grey,
child: ValueListenableBuilder<double>(
valueListenable: _rowHeight,
builder: (_, __, ___) => Row(
key: _rowKey,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
child: Text(
"T",
style: TextStyle(fontSize: 90),
),
color: Colors.green,
width: 200,
),
Container(
height: (_rowHeight.value<0)? null : _rowHeight.value,
child: Container(
child: Text(
"TTTTT",
style: TextStyle(fontSize: 20),
),
color: Colors.blue)),
],
),
),
),
);
}
}