最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Flutter Widget with Children that Grows Until Given Height then Scrolls - Stack Overflow

programmeradmin1浏览0评论

I would like to create a Flutter widget that is kind of a mix between a Column and a ListView. It must do the following:

  • It is given a list of children (be it Widgets or Slivers) and a maximum height it can be.
  • It lays out the first n children that fit its available space.
  • If everything fits - it basically becomes a Column with MainAxisSize.min
  • If sum of child sizes is bigger than max height then it behaves like a ListView and lays out lazily the rest of the children that do not fit the viewport

ListView.builder with shrinkWrap does not work, obviously, because of the lazy-loading constraint, and no-shrinkWrapping solution just makes the ListView take all the available space, even if it has a single child within its viewport.

So basically - as far as I understand - I need a Flutter equivalent of this behaviour

I would like to create a Flutter widget that is kind of a mix between a Column and a ListView. It must do the following:

  • It is given a list of children (be it Widgets or Slivers) and a maximum height it can be.
  • It lays out the first n children that fit its available space.
  • If everything fits - it basically becomes a Column with MainAxisSize.min
  • If sum of child sizes is bigger than max height then it behaves like a ListView and lays out lazily the rest of the children that do not fit the viewport

ListView.builder with shrinkWrap does not work, obviously, because of the lazy-loading constraint, and no-shrinkWrapping solution just makes the ListView take all the available space, even if it has a single child within its viewport.

So basically - as far as I understand - I need a Flutter equivalent of this behaviour

Share Improve this question asked Mar 6 at 12:11 BobLoblawBobLoblaw 378 bronze badges 1
  • Can you please add some of the demo type image that showcase what you actually need kind of figma UI video or what ever represent the UI. – Akshay Gupta Commented Mar 6 at 14:03
Add a comment  | 

2 Answers 2

Reset to default 0

This works for me.

First image shows the widget with fewer items, behaves like a column

Second image shows the widget with more items, behaves like a list view with lazy loading.

class ConstrainedListView extends StatefulWidget {
  const ConstrainedListView(
      {super.key,
      required this.children,
      required this.maxHeight,
      this.padding});

  final List<Widget> children;
  final double maxHeight;
  final EdgeInsets? padding;

  @override
  State<ConstrainedListView> createState() => _ConstrainedListViewState();
}

class _ConstrainedListViewState extends State<ConstrainedListView> {
  final GlobalKey _key = GlobalKey();

  double height = 0;

  @override
  Widget build(BuildContext context) {
    getHeight();
    return ConstrainedBox(
      key: _key,
      constraints: BoxConstraints(maxHeight: widget.maxHeight),
      child: SizedBox(
        child: ListView.builder(
          itemBuilder: (context, index) => widget.children[index],
          itemCount: widget.children.length,
          shrinkWrap: true,
          physics: height >= widget.maxHeight
              ? const AlwaysScrollableScrollPhysics()
              : const NeverScrollableScrollPhysics(),
          padding: widget.padding,
        ),
      ),
    );
  }

  void getHeight() {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      final renderBox = _key.currentContext?.findRenderObject() as RenderBox?;
      if (renderBox == null) return;
      final size = renderBox.size;
      if (height == size.height) return;
      height = size.height;

      setState(() {});
    });
  }
}

Have you tried the Flexible or Expanded components?

发布评论

评论列表(0)

  1. 暂无评论