flutterflutter-dependenciesflutter-appbarsliverappbar

How to make custom SliverAppBar in Flutter?


Sliver App Bar

Hello I guys, I am working on Sliver Appbar but I want this type of custom SliverAppbar,How can I achieve this?


Solution

  • You can try to simulate the same using SliverPersistentHeader Widget and a bunch of slivers included inside the CustomScrollView. All you need to do is give the AppBar, the SliverPersistentHeader and the first Sliver the same background color.

    Have a look at the code below (sorry for the bad formatting). I have also included a gif in the end as how it looks (sorry for the bad design).

      class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      static const String _title = 'Flutter Code Sample';
    
      @override
      Widget build(BuildContext context) {
        return const MaterialApp(
          title: _title,
          home: MyStatefulWidget(),
          debugShowCheckedModeBanner: false,
        );
      }
    }
    
    class MyStatefulWidget extends StatefulWidget {
      const MyStatefulWidget({Key? key}) : super(key: key);
    
      @override
      State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
    }
    
    class _MyStatefulWidgetState extends State<MyStatefulWidget> {
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(backgroundColor:  const Color(0xff222222),
                         title: const Text("JazzCash"),
                         elevation: 0,
                        actions: const [Icon(Icons.info), Icon(Icons.notifications)]),
          body: CustomScrollView(
            slivers: <Widget>[
              
              // persistent header
              SliverPersistentHeader(
                pinned: true,
                delegate: SliverAppBarDelegate(
            minHeight: 60.0,
            maxHeight: 60.0,
            child: Container(
                color: const Color(0xff222222), child:Row(children:
                    const [SizedBox(width: 10), CircleAvatar(), SizedBox(width: 10), Text("Muhammad", style: TextStyle(fontSize: 20, color: Colors.white)),
                    ])),
          ),
             ),
              SliverList(
              delegate: SliverChildListDelegate(
                [
                  
                  // first sliver
                  Container(color: const Color(0xff222222), 
                      padding: const EdgeInsets.all(10),
                      child: Column(crossAxisAlignment: CrossAxisAlignment.start,
                                                                    children: [const Text("Login -->", style: TextStyle(color: Colors.amber, fontSize: 25, fontWeight: FontWeight.bold)),
                                                                               const Text("to Make Payments", style: TextStyle(color: Colors.white, fontSize: 25, fontWeight: FontWeight.bold)),
                                                                               const SizedBox(height: 10),
                                                                               Row(children: [ElevatedButton(onPressed: (){}, child: const Text("Add money")), const SizedBox(width: 20), ElevatedButton(onPressed: (){}, child: const Text("Add account"))])
                                                                              ])),
                  Container(color: Colors.purple, height: 150.0),
                  Container(color: Colors.green, height: 150.0),
            ],
            ),
            ),
            ],
          ),
        );
      }
    }
    
    // defining delegate for sliverpersistendheader
    class SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
      SliverAppBarDelegate({
        @required this.minHeight,
        @required this.maxHeight,
        @required this.child,
      });
      final double? minHeight;
      final double? maxHeight;
      final Widget? child;
      @override
      double get minExtent => minHeight!;
      @override
      double get maxExtent => math.max(maxHeight!, minHeight!);
      @override
      Widget build(
          BuildContext context, 
          double shrinkOffset, 
          bool overlapsContent) 
      {
        return SizedBox.expand(child: child);
      }
      @override
      bool shouldRebuild(SliverAppBarDelegate oldDelegate) {
        return maxHeight != oldDelegate.maxHeight ||
            minHeight != oldDelegate.minHeight ||
            child != oldDelegate.child;
      }
    }
    

    Result