0

have a question about flutter's CustomScrollView

What I have now is:

@override
Widget build(BuildContext context) {
  return Container(
    child: CustomScrollView(
      shrinkWrap: true,
      slivers: <Widget>[
        SliverPadding(
          padding: EdgeInsets.all(0),
          sliver: SliverList(
            delegate: SliverChildListDelegate(
              <Widget>[
                Card(),
                Card(),
                Container(
                  child: ListView.builder(
                    physics: const NeverScrollableScrollPhysics(),
                  ),
                )
              ],
            ),
          ),
        ),
      ],
    ),
  );
}

*code was simplified as it's an example.

As you can see there are 2 Cards() and a Container with ListView inside. Both cards has fixed height, the container with list has dynamic height. How it works now: as ListView grow up we can scroll to the bottom of the list. So normally both Card widgets became invisible because List's elements take all the screen.

The idea is to force second Card() to be pinned to the top of the screen. So basically it's should be on it's own place, but with more and more scrolling it should be pinned to the top of the screen while I'm scrolling list more and more. The question is how can I do something like this?

Thanks!

1
  • do you want only the second card to be pinned to the top? Commented Feb 15, 2019 at 15:45

1 Answer 1

2

You could use SliverPersistentHeader, I prepared this sample for you:

      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: SafeArea(
            child: CustomScrollView(
              slivers: <Widget>[
                SliverPadding(
                  padding: EdgeInsets.all(0),
                  sliver: SliverList(
                      delegate: SliverChildBuilderDelegate(
                    (context, index) {
                      return ListTile(
                        title: Text("index: $index"),
                      );
                    },
                    childCount: 3,
                  )),
                ),
                SliverPersistentHeader(
                  pinned: true,
                  delegate: PersistentHeader("Card 1"),
                ),
                SliverPersistentHeader(
                  pinned: true,
                  delegate: PersistentHeader("Card 2"),
                ),
                SliverPadding(
                  padding: EdgeInsets.all(0),
                  sliver: SliverList(
                      delegate: SliverChildBuilderDelegate((context, index) {
                    return ListTile(
                      title: Text("index: $index"),
                    );
                  })),
                ),
              ],
            ),
          ),
        );
      }
    }

    class PersistentHeader extends SliverPersistentHeaderDelegate {
      final String title;

      PersistentHeader(this.title);

      @override
      Widget build(
          BuildContext context, double shrinkOffset, bool overlapsContent) {
        return Container(
          color: Colors.white,
          child: Card(
            color: Colors.white,
            elevation: 7.0,
            child: SizedBox(height: 100.0, child: Center(child: Text(title))),
          ),
        );
      }

      @override
      double get maxExtent => 100.0;

      @override
      double get minExtent => 100.0;

      @override
      bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) {
        return false;
      }
    }

More info: https://docs.flutter.io/flutter/widgets/SliverPersistentHeader-class.html

Sign up to request clarification or add additional context in comments.

2 Comments

thanks. That's work for me. Have one more question. What is the best way to transfer data between these objects? I mean between card 1, card 2 and list. Since they are currently in different classes.
I've tried to use it, but it isn't help. I mean: Inherited widget contains final Object. I'm modifying some fields of that final object from different places. The thing is I want changes of object fields to rebuild the whole tree of InheritedWidget. Where am I wrong? Is this InheritedWidget case?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.