LimitedBox 与 ConstrainedBox 中的 ListView

ListView in LimitedBox vs ConstrainedBox

在尝试弄清楚如何限制 ListView 的大小时,我在 Whosebug 中看到示例建议做一些事情,比如将 ListView 放在 LimitedBox 中并设置 Limited 框的 maxHeight 和 ListView 的收缩包装,会完成它。但是,ListView 仍会增长超过 maxheight 以适应 ListView 中子级的大小。

最终,我尝试了一个使用 ConstrainedBox 的例子,并设置了它的 maxHeight 和 ListView 的 Shrinkwrap;这样做似乎实现了将 Listview 高度限制为 maxHeight 设置的预期结果。

有人能帮我理解为什么 LimitedBox maxHeight 在这种情况下不起作用,而 ConstrainedBox 可以吗?

这是一个没有将自身限制为最大高度的 LimitedBox 示例:

Widget _getPopupCard(){
    return Hero(
      tag: 0,
      createRectTween: (begin,end){
        return MaterialRectCenterArcTween(begin: begin, end: end);
      },
      child: Container(
        child:Padding(
          padding: EdgeInsets.all(14), 
          child: Material(
            borderRadius: BorderRadius.circular(18), 
            color: Colors.white, 
            child:  LimitedBox(
            maxHeight: 300,
              child: ListView(
                shrinkWrap: true,
                  children:  _getTiles(),
                ),
            ),
            ),
          ),
        ),
    );
  }

这是一个将自身限制为 maxHeight 的 ConstrainedBox 版本的示例:

Widget _getPopupCard(){
  return Hero(
    tag: 0,
    createRectTween: (begin,end){
      return MaterialRectCenterArcTween(begin: begin, end: end);
    },
    child: Container(
      child:Padding(
        padding: EdgeInsets.all(14), 
        child: Material(
          borderRadius: BorderRadius.circular(18), 
          color: Colors.white, 
          child:  ConstrainedBox(
            constraints: BoxConstraints(maxHeight: 300.0),
            child: ListView(
              shrinkWrap: true,
              children:  _getTiles(),
            ),
          ),
        ),
      ),
    ),
  );
}

https://api.flutter-io.cn/flutter/widgets/LimitedBox-class.html

LimitedBox : 仅在不受约束时限制其大小的框。

ConstrainedBox :它在所有情况下都应用其约束,而不仅仅是在传入约束不受限制时。

LimitedBox 只能在父级无约束且 flutter 无法渲染无限时工作width/heigh,因此 LimitedBox 必须同时提供 MaxWidth 和 MaxHeight

您可以包装 UnconstrainedBox 以使 LimitedBox 工作,但您真的不需要这个...请参阅:https://www.woolha.com/tutorials/flutter-using-limitedbox-widget-examples

https://dartpad.dev/2cfc997a7984bf848687f209cba917ce?null_safety=true

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'LimitedBox',
      home: Scaffold(
        appBar: AppBar(
            title:
                Text('LimitedBox can only work when parent is unconstrainted')),
        body: Center(
          child: UnconstrainedBox( // wrap UnconstrainedBox to make LimitedBox works, but you really don't need this... https://www.woolha.com/tutorials/flutter-using-limitedbox-widget-examples
            child: _getPopupCard(),
          ),
        ),
      ),
    );
  }
}

Widget _getPopupCard() {
  return LimitedBox(
    maxHeight: 300.0,
    maxWidth: 300.0,
    child: ListView(
      shrinkWrap: true,
      children: _getTiles(),
    ),
  );
}

List<Widget> _getTiles() {
  return List.generate(100, (int i) => i).map((int i) {
    return Container(
      color: i % 2 == 0 ? Colors.red : Colors.green,
      child: Center(child: Text("$i")),
    );
  }).toList();
}

更新:

Is Container the constrained parent that is overriding the LimitedBox even though I didn't set height or width on the Container?

我搜索这个问题只是因为我正在阅读本指南:https://flutter.dev/docs/development/ui/layout/constraints 容器的布局行为有点复杂。

关于这个,我在下面 运行 代码,似乎 flutter 会给 Container 一个默认的 Constraints。 Container 源代码说明了一些情况,也许您应该从源代码中获取一些信息。

  runApp(
    MaterialApp(
      home: UnconstrainedBox(
        child: LayoutBuilder(
          builder: (ctx, Constraints constraints) {
            print(ctx);
            print(constraints);//BoxConstraints(unconstrained)
            return Text("hello world");
          },
        ),
      ),
    ),
  );

  runApp(
    MaterialApp(
      home: Container(
        color: Colors.white,
        child: LayoutBuilder(
          builder: (ctx, constraints) {
            print(ctx);
            print(constraints); // BoxConstraints(w=500.0, h=296.0)
            return Text("hello world333333");
          },
        ),
      ),
    ),
  );