Flutter: combining SliverAppbar with Column widget
Asked Answered
E

4

9

I'm trying to make an event page for an app where user can view events that have a banner image and some other useful information. I really like the idea of implementing a SliverAppBar with the banner, so that the user can scroll to see more information. For this I seem to need a CustomScrollView with a SliverAppBar and FlexibleSpaceBar.

All tutorials I have seen online assume that the rest of the screen should be a list of sorts, but I rather want something like a Column widget. A Column has unbounded height, however, which causes overflow errors in the CustomScrollView. I could wrap it in a Container with specified height, but the contents of the body are of variable size, so that is not ideal. Is there a way to have a SliverAppBar and a Column work side by side?

I want something along the lines of this:

class ActivityPage extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(slivers: [
          SliverAppBar(
            flexibleSpace: FlexibleSpaceBar(
              background: Image(someImage),
            ),
            expandedHeight: Image,
            floating: false,
            pinned: true,
            snap: false,
          ),
          Column(
            children: [
              someChildren,
            ]
            ),
          )
        ]),
      ),
    );
  }

It should be possible, because it seems to me a somewhat common pattern, but I have looked around a lot and I can only find examples where the body consists of lists...

Enliven answered 3/11, 2020 at 0:18 Comment(0)
E
10

For anyone having the same struggle: here's the solution I just found:

Widget build(BuildContext context) {
    return Scaffold(
      body: NestedScrollView(
        headerSliverBuilder:
            (BuildContext context, bool innerBoxIsScrolled) {
          return <Widget>[
            SliverAppBar(
              backgroundColor: this.color,
              flexibleSpace: FlexibleSpaceBar(
              background: YourImage(),
              ),
            )
          ];
          },
        body: Container(
          child: Builder(builder: (context) {
            return Column(
              mainAxisAlignment: MainAxisAlignment.start,
                children: [
                  WidgetOne(),
                  WidgetTwo()
                ]);
          })),
        ),
      )),
    );
  }

Enliven answered 13/11, 2020 at 10:35 Comment(0)
R
13

Use SliverList and SliverChildListDelegate instead of a Column.

Widget build(BuildContext context) {
  return Scaffold(
    body: CustomScrollView(
      slivers: <Widget>[
        SliverAppBar(
          expandedHeight: 200,
          flexibleSpace: FlexibleSpaceBar(
            background: Container(color: Colors.green),
          ),
        ),
        SliverList(
          delegate: SliverChildListDelegate([
            Container(color: Colors.yellow, height: 400),
            Container(color: Colors.red, height: 800),
          ]),
        ),
      ],
    ),
  );
}
Reginaldreginauld answered 21/8, 2021 at 7:34 Comment(0)
E
10

For anyone having the same struggle: here's the solution I just found:

Widget build(BuildContext context) {
    return Scaffold(
      body: NestedScrollView(
        headerSliverBuilder:
            (BuildContext context, bool innerBoxIsScrolled) {
          return <Widget>[
            SliverAppBar(
              backgroundColor: this.color,
              flexibleSpace: FlexibleSpaceBar(
              background: YourImage(),
              ),
            )
          ];
          },
        body: Container(
          child: Builder(builder: (context) {
            return Column(
              mainAxisAlignment: MainAxisAlignment.start,
                children: [
                  WidgetOne(),
                  WidgetTwo()
                ]);
          })),
        ),
      )),
    );
  }

Enliven answered 13/11, 2020 at 10:35 Comment(0)
K
1

Use ListView instead of Column. ListView has dynamic size

Krouse answered 2/2, 2021 at 6:0 Comment(0)
O
-1

For me the best way is to use SliverToBoxAdapter. Just wrap your Column in a Container and then wrap this Container in a SliverToBoxAdapter and it should work fine.

Outermost answered 30/7, 2021 at 13:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.