flutter 将SliverFillRemaining与CustomScrollView和SliverList一起使用

lh80um4z  于 2023-04-22  发布在  Flutter
关注(0)|答案(5)|浏览(183)

我正在尝试创建一个滚动列表,可以在滚动列表的底部有一个页脚。如果列表没有填满所有的垂直屏幕空间,页脚将需要向下移动到页面的底部。
我尝试在CustomScrollView中使用SliverListSliverFillRemaining来实现这个功能,但是我认为SliverFillRemaining显示了一些意想不到的行为,它占用了比需要的更多的空间(参见gif)。
我使用以下代码创建了这个列表:

child: new CustomScrollView(
  slivers: <Widget>[
    new SliverList(
      delegate: new SliverChildBuilderDelegate(
        (BuildContext context, int index) {
          return new Card(
            child: new Container(
              padding: new EdgeInsets.all(20.0),
              child: new Center(child: new Text("Card $index")),
            ),
          );
        },
        childCount: 3,
      ),
    ),
    new SliverPadding(
      padding: new EdgeInsets.all(5.0),
    ),
    new SliverFillRemaining(
      child: new Container(
        color: Colors.red,
      ),
    )
  ],
)

uidvcgyl

uidvcgyl1#

对于任何正在寻找答案的人,我有一个解决方案,一直工作得很好,每当我需要类似的东西。
我是这样做到的:

class ScrollOrFitBottom extends StatelessWidget {
  final Widget scrollableContent;
  final Widget bottomContent;

  ScrollOrFitBottom({this.scrollableContent, this.bottomContent});

  @override
  Widget build(BuildContext context) {
    return CustomScrollView(
      slivers: <Widget>[
        SliverFillRemaining(
          hasScrollBody: false,
          child: Column(
            children: <Widget>[
              Expanded(child: scrollableContent),
              bottomContent
            ],
          ),
        ),
      ],
    );
  }
}

顾名思义,如果内容太多,它会滚动,否则会将某些内容推到底部。
我认为这是简单和不言自明的,但让我知道,如果你有任何问题
示例:https://codepen.io/lazarohcm/pen/xxdWJxb

8ftvxx2r

8ftvxx2r2#

SliverFillRemaining会自动调整大小,以填充最后一个列表项的底部和视口底部之间的空间。有关代码,请参阅SliverFillRemainingperformLayout方法:
https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/rendering/sliver_fill.dart#L118
我不认为你可以用它来达到你想要的效果,尽管你可以创建一个子类来工作。

hmtdttj4

hmtdttj43#

Scaffold(
  appBar: AppBar(title: Text('SliverFillRemaining')),
  body: CustomScrollView(
    slivers: [
      SliverFillRemaining(
        hasScrollBody: false,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: const [
            FlutterLogo(size: 200),
            Text(
              'This is some longest text that should be centered'
              'together with the logo',
              textAlign: TextAlign.center,
            ),
          ],
        ),
      ),
    ],
  ),
);
bis0qfac

bis0qfac4#

This Package做的正是你所期望的,我已经尝试了几天了,最后用这个,它的工作方式与SliverToBoxAdapter相同,但扩展足够,不会导致过度滚动

child: new CustomScrollView(
  slivers: <Widget>[
    new SliverList(
      delegate: new SliverChildBuilderDelegate(
        (BuildContext context, int index) {
          return new Card(
            child: new Container(
              padding: new EdgeInsets.all(20.0),
              child: new Center(child: new Text("Card $index")),
            ),
          );
        },
        childCount: 3,
      ),
    ),
    new SliverPadding(
      padding: new EdgeInsets.all(5.0),
    ),
    new SliverFillRemainingBoxAdapter(
      child: new Container(
        color: Colors.red,
      ),
    )
  ],
)
pw9qyyiw

pw9qyyiw5#

请看我的答案here和一个Gist文件here。它可能会引导你走向正确的方向。

@override
Widget build(BuildContext context) {
  return LayoutBuilder(
    builder: (BuildContext context, BoxConstraints constraints) {
      return SingleChildScrollView(
        child: ConstrainedBox(
          constraints: constraints.copyWith(
            minHeight: constraints.maxHeight,
            maxHeight: double.infinity,
          ),
          child: IntrinsicHeight(
            child: Column(
              children: <Widget>[
                Container(height: 200, color: Colors.blue),
                Container(height: 200, color: Colors.orange),
                Container(height: 200, color: Colors.green),
                Container(height: 50, color: Colors.pink),
                Expanded(
                  child: Align(
                    alignment: Alignment.bottomCenter,
                    child: Container(
                      width: double.infinity,
                      color: Colors.red,
                      padding: EdgeInsets.all(12.0),
                      child: Text('FOOTER', textAlign: TextAlign.center,),
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
      );
    }
  );
}

相关问题