SliverAppBar only push up after some scrolling

Issue

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.

Answered By – Hugo Passos

Answer Checked By – Robin (FlutterFixes Admin)

Leave a Reply

Your email address will not be published.