Search code examples
flutterflutter-sliverflutter-appbar

SliverAppBar only push up after some scrolling


I have a SliverAppBar (floating: true, pinned: false).

I want to achieve that the user has to scroll 200 pixels (or some other amount) before the SliverAppBar starts to compress/slide-up.


Solution

  • The problem here is that pinned value is not supposed to be changed. If you try to change it after scrolling 200 pixels, the SliverAppBar would shrink suddenly.

    You can check this out by running the code below:

    class Buster extends StatefulWidget {
      @override
      _BusterState createState() => _BusterState();
    }
    
    class _BusterState extends State<Buster> {
      ScrollController controller;
      bool isAppBarPinned;
    
      @override
      void initState() {
        super.initState();
        controller = ScrollController()..addListener(onScroll);
        isAppBarPinned = true;
      }
    
      void onScroll() {
        if (controller.position.pixels > 200) {
          if (isAppBarPinned) {
            setState(() => isAppBarPinned = false);
          }
        } else {
          if (!isAppBarPinned) {
            setState(() => isAppBarPinned = true);
          }
        }
      }
    
      @override
      void dispose() {
        controller.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: CustomScrollView(
            controller: controller,
            slivers: [
              SliverAppBar(
                title: Text('Buster'),
                floating: true,
                pinned: isAppBarPinned,
              ),
              SliverFixedExtentList(
                itemExtent: 150,
                delegate: SliverChildListDelegate(
                  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
                      .map((int index) => Center(child: Text('Item #$index')))
                      .toList(),
                ),
              )
            ],
          ),
        );
      }
    }
    

    So I think the best option you got here is using a regular AppBar and animate it manually with a Transform.