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)),
            ],
          ),
        ),
      ),
    );
  }
}