【问题标题】:Expand Widget to fill remaining space in ListView展开 Widget 以填充 ListView 中的剩余空间
【发布时间】:2026-01-24 08:30:01
【问题描述】:

如上图所示,我希望小部件 2 始终至少是剩余可用空间的高度。

但是小部件 2 可能包含太多的 ListTiles,因此如果不滚动它们就无法显示。但是滚动应该会影响小部件 1 和小部件 2。实现此类功能的最佳方法是什么?

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    Widget 2 包装在Expanded 小部件中。

    要滚动Widget 1Widget 2,请将它们都包装在SingleChildScrollView 小部件中。

    【讨论】:

    • 这不起作用,因为展开的小部件想要无限展开,这会在放置在可滚动小部件中时导致异常,因为它允许孩子们随意展开
    • 请在此处输入您的代码。我们会更容易为您提供帮助。
    • 我不能这样做,因为它太复杂了。这也没关系,因为我当前的实现并没有按照我想要的方式工作。这只是一种变通方法,当屏幕尺寸太小时不起作用。
    • 它应该以这种方式工作。我认为还有其他东西阻碍了扩展小部件的正确使用,可能是硬编码的高度值。
    【解决方案2】:

    一种简单的方法是将您的小部件放置在 Column 中并用单个子滚动视图包装它。对于 ListView 使用 shrinkWrap 作为 true 和物理你可以设置为 NeverScrollableScrollPhysics

    这是一个例子

    SingleChildScrollView(
      child: Column(
        children: [
          Container(
            height: MediaQuery.of(context).size.height / 2,
            color: Colors.red,
          ),
          ListView.builder(
            shrinkWrap:true,
            physics:NeverScrollableScrollPhysics(),
            itemCount: 100,
            itemBuilder: (context, index) => Text("$index"),
          ),
        ],
      ),
    );
    

    希望这会有所帮助!

    【讨论】:

      【解决方案3】:

      如果您可以区分元素少和多的情况(例如在加载过程中),您可以使用CustomScrollViewSliverFillRemaining

        var _isLoading = true;
      
        @override
        Widget build(BuildContext context) {
          return CustomScrollView(
            slivers: [
              _buildWidget1(),
              _buildWidget2(),
            ],
          );
        }
      
        Widget _buildWidget1() {
          return SliverToBoxAdapter(
            child: Container(height: 400, color: Colors.blue),
          );
        }
      
        Widget _buildWidget2() {
          if(_isLoading) {
            return SliverFillRemaining(
              hasScrollBody: false,
              child: Center(child: const CircularProgressIndicator()),
            );
          } else {
            return SliverFixedExtentList(
              delegate: SliverChildBuilderDelegate(
                _buildItem,
                childCount: childCount,
              ),
              itemExtent: 56,
            );
          }
        }
      

      【讨论】: