Search code examples
androidiosflutterflutter-animationflutter-sliver

Implementing snapConfiguration to SliverPersistentHeader


I am trying to implement snap feature to SliverPersistentHeader but couldn't figure it out and couldn't find a good documentation on this.

My code:

    class MyDelegate extends SliverPersistentHeaderDelegate  {
      double he;
    
      MyDelegate ({required this.he}) : super();
    
      @override
      Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
        return AnimatedContainer(
          child: const Text('Title', textAlign: TextAlign.center, style: TextStyle(fontSize: 24),),
          color: Colors.green,
          height: he,
          duration: const Duration(milliseconds: 100),
        );
      }
    
      @override
      double get maxExtent => kToolbarHeight;
    
      @override
      double get minExtent => 0;
    
      @override
      bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) {
        return true;
      }
    
      @override
      FloatingHeaderSnapConfiguration get snapConfiguration => FloatingHeaderSnapConfiguration();    
    }

Floating is set to true.

I am getting error message for vsync being null.
I couldn't make it work. I need help on implementing snap feature for SliverPersistenHeader.


Solution

  • I managed to solve the issue. Only thing I needed to do was providing vsync.
    For that I need to add with TickerProviderStateMixin to my code:

    class _CustomBodyState extends State<CustomBody> with TickerProviderStateMixin {
    

    and in the build method vsync: this:

    child: CustomScrollView(
            controller: _scrollController,
            slivers: [
              SliverPersistentHeader(delegate: MyDelegate(minExtent: 0, maxExtent: kToolbarHeight, vsync: this), floating: true),
              const CustomSliverListTile(),
            ],
          ),
    

    and changed the MyDelegate as:

    class MyDelegate extends SliverPersistentHeaderDelegate  {
      @override
      final double minExtent;
      @override
      final double maxExtent;
      @override
      final TickerProvider vsync;
    
      MyDelegate ({required this.minExtent, required this.maxExtent, required this.vsync}) : super();
    
      @override
      Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
        return Container(
          child: const Text('Title', textAlign: TextAlign.center, style: TextStyle(fontSize: 24),),
          color: Colors.green,
          height: maxExtent,
        );
      }
    
      @override
      bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) {
        return true;
      }
    
    @override 
      FloatingHeaderSnapConfiguration get snapConfiguration => FloatingHeaderSnapConfiguration(
        curve: Curves.linear, 
        duration: const Duration(milliseconds: 100),
      );
    }