user3612643
user3612643

Reputation: 5772

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.

Upvotes: 2

Views: 1273

Answers (1)

Hugo Passos
Hugo Passos

Reputation: 8427

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.

Upvotes: 3

Related Questions