How to Add SliverAppBar with Pinned TabBar in Flutter?

Spread the love
How to Add SliverAppBar with Pinned TabBar in Flutter
How to Add SliverAppBar with Pinned TabBar in Flutter

Introduction

In Flutter, a SliverAppBar with a pinned TabBar is a powerful combination that allows you to create a flexible and interactive app header. The SliverAppBar provides a collapsible header that adjusts its size based on the scroll position, while the pinned TabBar offers a set of tabs that stay visible at the top. In this tutorial, you will learn how to add a SliverAppBar with a pinned TabBar in Flutter to enhance your app’s navigation and user experience.

Content: To add a SliverAppBar with a pinned TabBar in Flutter, follow these steps:

Content

Step 1. Create a new Flutter project:

Ensure that you have Flutter installed on your machine. Open your terminal and run the following command to create a new Flutter project:

Step 2. Implement the SliverAppBar with Pinned TabBar:

Navigate to the lib folder of your Flutter project and open the main.dart file. Replace the existing code with the following implementation:


import 'package:flutter/material.dart';

class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget>
    with SingleTickerProviderStateMixin {
  late TabController _tabController;

  @override
  void initState() {
    super.initState();
    _tabController = TabController(length: 3, vsync: this);
  }

  @override
  void dispose() {
    _tabController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: NestedScrollView(
        headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
          return <Widget>[
            SliverAppBar(
              elevation: 1,
              backgroundColor: Color.fromARGB(255, 255, 255, 255),
              title: Text(
                "Appbar title",
                style: TextStyle(
                  fontWeight: FontWeight.w800,
                  color: Color.fromARGB(255, 255, 157, 0),
                ),
              ),
              leading: IconButton(
                onPressed: () {},
                icon: Icon(
                  Icons.arrow_back,
                  color: Color.fromARGB(255, 255, 157, 0),
                  size: 30.0,
                ),
              ),
              actions: [
                IconButton(
                  onPressed: () {},
                  icon: Icon(
                    Icons.notification_add,
                    color: Color.fromARGB(255, 255, 157, 0),
                    size: 30.0,
                  ),
                ),
              ],
              pinned: true,
              expandedHeight: 250.0,
              flexibleSpace: FlexibleSpaceBar(
                background: Container(
                  decoration: BoxDecoration(
                    image: DecorationImage(
                      image: NetworkImage(
                          "https://media.istockphoto.com/id/1290692464/photo/teamwork-network-and-community-concept.jpg?s=612x612&w=0&k=20&c=mfmO8j68TjNnoGki0UJe58SKfqyNgIp3lHDSJ0OkVo0="),
                      fit: BoxFit.cover,
                    ),
                  ),
                  child: Center(
                    child: Column(
                      children: [
                        SizedBox(
                          height: 100,
                        ),
                        Text(
                          'SliverAppBar with Pinned TabBar',
                          style: TextStyle(
                            fontSize: 24.0,
                            fontWeight: FontWeight.bold,
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
              ),
            ),
            SliverPersistentHeader(
              pinned: true,
              delegate: _SliverAppBarDelegate(
                TabBar(
                  indicatorColor: Colors.black,
                  unselectedLabelColor: Colors.black,
                  controller: _tabController,
                  tabs: [
                    Tab(text: 'Tab 1'),
                    Tab(text: 'Tab 2'),
                    Tab(text: 'Tab 3'),
                  ],
                ),
              ),
            ),
          ];
        },
        body: TabBarView(
          controller: _tabController,
          children: [
            Center(child: Text('Tab 1 Content')),
            Center(child: Text('Tab 2 Content')),
            Center(child: Text('Tab 3 Content')),
          ],
        ),
      ),
    );
  }
}

class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
  final TabBar _tabBar;

  _SliverAppBarDelegate(this._tabBar);

  @override
  double get minExtent => _tabBar.preferredSize.height;
  @override
  double get maxExtent => _tabBar.preferredSize.height;

  @override
  Widget build(
      BuildContext context, double shrinkOffset, bool overlapsContent) {
    return Container(
      color: Colors.white,
      child: _tabBar,
    );
  }

  @override
  bool shouldRebuild(_SliverAppBarDelegate oldDelegate) {
    return false;
  }
}

void main() {
  runApp(MaterialApp(
    debugShowCheckedModeBanner: false,
    home: MyWidget(),
  ));
}

In this code snippet, we define a Flutter app that utilizes a CustomScrollView with SliverAppBar and SliverFillRemaining. The pinned property of SliverAppBar ensures that it stays visible at the top while scrolling. The TabBar and TabBarView are wrapped inside a DefaultTabController to handle tab navigation

Step 3. Run the App:

Save the changes made to the main.dart file and execute the following command in your terminal to run the app:

Sample Code:


import 'package:flutter/material.dart';

class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget>
    with SingleTickerProviderStateMixin {
  late TabController _tabController;

  @override
  void initState() {
    super.initState();
    _tabController = TabController(length: 3, vsync: this);
  }

  @override
  void dispose() {
    _tabController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: NestedScrollView(
        headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
          return <Widget>[
            SliverAppBar(
              elevation: 1,
              backgroundColor: Color.fromARGB(255, 255, 255, 255),
              title: Text(
                "Appbar title",
                style: TextStyle(
                  fontWeight: FontWeight.w800,
                  color: Color.fromARGB(255, 255, 157, 0),
                ),
              ),
              leading: IconButton(
                onPressed: () {},
                icon: Icon(
                  Icons.arrow_back,
                  color: Color.fromARGB(255, 255, 157, 0),
                  size: 30.0,
                ),
              ),
              actions: [
                IconButton(
                  onPressed: () {},
                  icon: Icon(
                    Icons.notification_add,
                    color: Color.fromARGB(255, 255, 157, 0),
                    size: 30.0,
                  ),
                ),
              ],
              pinned: true,
              expandedHeight: 250.0,
              flexibleSpace: FlexibleSpaceBar(
                background: Container(
                  decoration: BoxDecoration(
                    image: DecorationImage(
                      image: NetworkImage(
                          "https://media.istockphoto.com/id/1290692464/photo/teamwork-network-and-community-concept.jpg?s=612x612&w=0&k=20&c=mfmO8j68TjNnoGki0UJe58SKfqyNgIp3lHDSJ0OkVo0="),
                      fit: BoxFit.cover,
                    ),
                  ),
                  child: Center(
                    child: Column(
                      children: [
                        SizedBox(
                          height: 100,
                        ),
                        Text(
                          'SliverAppBar with Pinned TabBar',
                          style: TextStyle(
                            color: Colors.tealAccent,
                            fontSize: 24.0,
                            fontWeight: FontWeight.bold,
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
              ),
            ),
            SliverPersistentHeader(
              pinned: true,
              delegate: _SliverAppBarDelegate(
                TabBar(
                  indicatorColor: Colors.black,
                  // indicatorWeight: 10,
                  labelStyle: TextStyle(fontWeight: FontWeight.w700),
                  // labelPadding: EdgeInsets.symmetric(vertical: 100),
                  labelColor: Color.fromARGB(255, 255, 157, 0),
                  unselectedLabelColor: Colors.black,
                  controller: _tabController,
                  tabs: [
                    Tab(text: 'Tab 1'),
                    Tab(text: 'Tab 2'),
                    Tab(text: 'Tab 3'),
                  ],
                ),
              ),
            ),
          ];
        },
        body: TabBarView(
          controller: _tabController,
          children: [
            Center(child: Text('Tab 1 Content')),
            Center(child: Text('Tab 2 Content')),
            Center(child: Text('Tab 3 Content')),
          ],
        ),
      ),
    );
  }
}

class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
  final TabBar _tabBar;

  _SliverAppBarDelegate(this._tabBar);

  @override
  double get minExtent => _tabBar.preferredSize.height;
  @override
  double get maxExtent => _tabBar.preferredSize.height;

  @override
  Widget build(
      BuildContext context, double shrinkOffset, bool overlapsContent) {
    return Container(
      color: Colors.white,
      child: _tabBar,
    );
  }

  @override
  bool shouldRebuild(_SliverAppBarDelegate oldDelegate) {
    return false;
  }
}

void main() {
  runApp(MaterialApp(
    debugShowCheckedModeBanner: false,
    home: MyWidget(),
  ));
}

Output:

How to Add SliverAppBar with Pinned TabBar in Flutter
How to Add SliverAppBar with Pinned TabBar in Flutter

 

 

Conclusion:

Congratulations! You have successfully added a SliverAppBar with a pinned TabBar in your Flutter app. By following this tutorial, you learned how to create a flexible app header with scrollable tabs, enhancing the navigation and user experience. Experiment with different configurations to customize the appearance and behavior of your SliverAppBar and TabBar as per your app requirements.

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *