如何使父 ListView 框的大小与嵌套 ListView 中最大的子框大小相同?

How to make parent ListView box size the same as it's largest child in a nested ListView?

在过去的几天里,我一直在努力完成这项工作,但运气不佳。

我有两个 ListView,一个在另一个里面(嵌套)。我希望父 ListView 中的项目与其最大的 ListView 子项具有相同的大小。

这可能吗?如果有怎么办?

如果您需要更多信息,请告诉我。

跳出框框思考!
在某些情况下,您应该编写自己的自定义小部件。

我写了一个可以帮助你解决这个问题的小部件:

class CustomListView extends StatelessWidget {
  final Widget Function(BuildContext, int) sepratorBuilder;
  final Widget Function(BuildContext, int) itemBuilder;
  final int itemCount;
  final Axis scrollDirection;
  final List<Widget> children;
  final EdgeInsetsGeometry padding;

  CustomListView({
    @required this.children,
    this.padding = const EdgeInsets.all(0),
    this.scrollDirection = Axis.vertical,
    // You can add any other property that you want ...
  })  : assert(children != null),
        assert(padding != null),
        assert(scrollDirection != null),
        itemBuilder = null,
        itemCount = null,
        sepratorBuilder = null;

  CustomListView.builder({
    @required this.itemBuilder,
    @required this.itemCount,
    this.padding = const EdgeInsets.all(0),
    this.scrollDirection = Axis.vertical,
    // You can add any other property that you want ...
  })  : assert(itemBuilder != null),
        assert(itemCount != null && itemCount >= 0),
        assert(padding != null),
        assert(scrollDirection != null),
        children = List.generate(
          itemCount,
          (index) => Builder(builder: (context) => itemBuilder(context, index)),
        ),
        sepratorBuilder = null;

  CustomListView.seprated({
    @required this.itemBuilder,
    @required this.itemCount,
    @required this.sepratorBuilder,
    this.padding = const EdgeInsets.all(0),
    this.scrollDirection = Axis.vertical,
    // You can add any other property that you want ...
  })  : assert(itemBuilder != null),
        assert(itemCount != null && itemCount >= 0),
        assert(padding != null),
        assert(scrollDirection != null),
        assert(sepratorBuilder != null),
        children = List.generate(
          itemCount,
          (index) => Builder(
            builder: (context) => Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                itemBuilder(context, index),
                if (index < itemCount - 1) sepratorBuilder(context, index),
              ],
            ),
          ),
        );

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      scrollDirection: scrollDirection,
      child: Padding(
        padding: padding,
        child: scrollDirection == Axis.vertical
            ? Column(
                mainAxisAlignment: MainAxisAlignment.center,
                mainAxisSize: MainAxisSize.min,
                children: children,
              )
            : Row(
                mainAxisAlignment: MainAxisAlignment.center,
                mainAxisSize: MainAxisSize.min,
                children: children,
              ),
      ),
    );
  }
}

你可以这样使用它:

class HomePage extends StatelessWidget {
  Widget itemBuilder(BuildContext context, int index) => Row(
        mainAxisAlignment: MainAxisAlignment.center,
        mainAxisSize: MainAxisSize.min,
        children: List.generate(
          3,
          (index) => Container(
            margin: const EdgeInsets.all(5),
            width: (Random().nextInt(50) + 50).toDouble(),
            height: 50,
            decoration: BoxDecoration(
              color: Color(
                (0xFFFFFFFF * Random().nextDouble()).floor() | 0xFF0000FF,
              ),
              borderRadius: const BorderRadius.all(Radius.circular(12.5)),
            ),
          ),
        ),
      );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.amber,
      body: Center(
        child: CustomListView.builder(
          padding: const EdgeInsets.only(top: 30, bottom: 30),
          itemCount: 20,
          itemBuilder: itemBuilder,
        ),
      ),
    );
  }
}

这是输出:


如果启用调试绘制,您可以看到 CustomListView 的宽度与其最宽的子项完全相同: