颤振:行横轴展开

时间:2018-06-18 17:36:51

标签: flutter flutter-layout

有没有办法给特定小部件提供行中最高小部件的高度?我不想在横轴上拉伸行。我只是希望所有小部件都具有最高小部件的高度。

2 个答案:

答案 0 :(得分:8)

当然!只需将您的行包装成IntrinsicHeight

即可
IntrinsicHeight(
  child: Row(
    crossAxisAlignment: CrossAxisAlignment.stretch,
    children: <Widget>[],
  ),
);

答案 1 :(得分:0)

有很多事情需要考虑。

受约束行的父级

IntrinsicHeight 仅适用于 if “无限高度可用”。相反,如果 Row 的父对象受到约束,它会工作 DartPad

  • 如果您想做的是扩展小部件的高度以匹配父级,只需执行以下操作:
Row(
 crossAxisAlignment: CrossAxisAlignment.stretch,
 ...
)

它会使所有小部件具有相同的高度,即使您将行的子级高度设置为不相等。它将忽略孩子的身高,并且不会使其他小部件与最高的一样。

无约束行的父级

  • 如果您事先知道最高小部件的高度,只需使用 Row 限制具有该高度的 SizedBox 的父级。
  • 如果没有,但您知道纵横比,请改用 AspectRatio,它是一个便宜得多的小部件。
AspectRatio(
        aspectRatio: 2, // try diff numbers
        child: Row(
          crossAxisAlignment: CrossAxisAlignment.stretch,
)
  • 如果您仍然不知道其中的任何一个(这种情况很少见),还有一些其他选项可以使用 LayoutBuilder 手动实现布局或创建新的小部件。
  • 如果这些工作都没有使用 IntrinsicHeight 作为 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');
  });
}

总结

您不太可能需要将同级小部件的高度与高度未知的单个小部件匹配。如果情况确实如此,则必须首先呈现和通知小部件,如 this 或间接使用 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)),
            ],
          ),
        ),
      ),
    );
  }
}