circle_bnb

A customizable circular bottom navigation bar for Flutter apps with smooth animations and multiple style options.

MIT License

Stars
0
Committers
2

circle_bnb

This package allows to make a circled bottom navigation bar at the bottom of the screen.

Getting Started

Add this to your package's pubspec.yaml file:

dependencies:
  circle_bnb: 0.0.1

Usage

Then you just have to import the package with

import 'package:circle_bnb/circle_bnb.dart';

Example

import 'package:flutter/material.dart';

import 'package:circle_bnb/circle_bnb.dart';

void main() => runApp(const App());

class App extends StatelessWidget {
  const App({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: const HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {

  int _currentIndex = 0;

  List<CircleBNBItem> pages = [
    CircleBNBItem(title: "Home", icon: Icons.home_outlined),
    CircleBNBItem(title: "Dashboard", icon: Icons.dashboard_outlined),
    CircleBNBItem(title: "Profile", icon: Icons.person_outlined),
    CircleBNBItem(title: "Explore", icon: Icons.explore_outlined),
    CircleBNBItem(title: "Settings", icon: Icons.settings_outlined),
    CircleBNBItem(title: "Notifications", icon: Icons.notifications_outlined),
    CircleBNBItem(title: "Saved", icon: Icons.bookmark_outline_outlined),
    CircleBNBItem(title: "Favorites", icon: Icons.favorite_outline_outlined),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text(
          'Circle BNB',
          style: TextStyle(
            color: Colors.white
          ),
        ),
        backgroundColor: Colors.primaries[_currentIndex],
        surfaceTintColor: Colors.transparent,
      ),
      body: IndexedStack(
        index: _currentIndex,
        children: List.generate(
          pages.length, (index) => ListView(
            children: List.generate(
              pages.length,
              (index2) => Container(
                color: Colors.primaries[(index + index2 >= 17) ? index2 : index + index2],
                height: MediaQuery.of(context).size.height * 0.5,
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: List.generate(
                    pages.length,
                    (index3) => Text(
                      pages[index3].title,
                      style: TextStyle(
                        color: index3 == _currentIndex ? Colors.white : Colors.white24
                      ),
                    ),
                  )
                ),
              ),
            )
          )
        )
      ),
      extendBody: true,
      backgroundColor: Colors.primaries[_currentIndex],
      bottomNavigationBar: CircleBNB(
        navigationStyle: NavigationStyle.circular,
        size: Size(
          MediaQuery.of(context).size.width * 0.75,
          MediaQuery.of(context).size.height * 0.235
        ),
        dragSpeed: 0.05,
        items: pages,
        onChangeIndex: (index) {
          setState(() {
            _currentIndex = index;
          });
        },
      ),
    );
  }
}
import 'package:flutter/material.dart';

import 'package:circle_bnb/circle_bnb.dart';

void main() => runApp(const App());

class App extends StatelessWidget {
  const App({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primaryColor: Colors.blue,
        highlightColor: Colors.transparent,
        splashColor: Colors.blue.shade200,
        bottomNavigationBarTheme: const BottomNavigationBarThemeData(
          selectedItemColor: Colors.blue,
          selectedLabelStyle: TextStyle(
            fontSize: 11,
            fontWeight: FontWeight.w600
          ),
          unselectedItemColor: Colors.black38,
          unselectedLabelStyle: TextStyle(
            fontSize: 10,
            fontWeight: FontWeight.w300
          ),
          showUnselectedLabels: true,
          backgroundColor: Colors.white,
          type: BottomNavigationBarType.fixed,
          elevation: 0,
        )
      ),
      home: const HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {

  int _currentIndex = 0;

  List<CircleBNBItem> pages = [
    CircleBNBItem(title: "Home", icon: Icons.home_outlined),
    CircleBNBItem(title: "Dashboard", icon: Icons.dashboard_outlined),
    CircleBNBItem(title: "Profile", icon: Icons.person_outlined),
    CircleBNBItem(title: "Explore", icon: Icons.explore_outlined),
    CircleBNBItem(title: "Settings", icon: Icons.settings_outlined),
    CircleBNBItem(title: "Notifications", icon: Icons.notifications_outlined),
    CircleBNBItem(title: "Saved", icon: Icons.bookmark_outline_outlined),
    CircleBNBItem(title: "Favorites", icon: Icons.favorite_outline_outlined),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text(
          'Circle BNB',
          style: TextStyle(
            color: Colors.white
          ),
        ),
        backgroundColor: Colors.primaries[_currentIndex],
        surfaceTintColor: Colors.transparent,
      ),
      body: IndexedStack(
        index: _currentIndex,
        children: List.generate(
          pages.length, (index) => ListView(
            children: List.generate(
              pages.length,
              (index2) => Container(
                color: Colors.primaries[(index + index2 >= 17) ? index2 : index + index2],
                height: MediaQuery.of(context).size.height * 0.5,
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: List.generate(
                    pages.length,
                    (index3) => Text(
                      pages[index3].title,
                      style: TextStyle(
                        color: index3 == _currentIndex ? Colors.white : Colors.white24
                      ),
                    ),
                  )
                ),
              ),
            )
          )
        )
      ),
      extendBody: true,
      backgroundColor: Colors.primaries[_currentIndex],
      bottomNavigationBar: CircleBNB(
        navigationStyle: NavigationStyle.linear,
        linearItemCount: 5,
        size: Size(
          MediaQuery.of(context).size.width * 0.75,
          MediaQuery.of(context).size.height * 0.235
        ),
        dragSpeed: 0.05,
        items: pages,
        onChangeIndex: (index) {
          setState(() {
            _currentIndex = index;
          });
        },
      ),
    );
  }
}

Example - Video

  • navigationStyle: NavigationStyle.circular

https://github.com/user-attachments/assets/3f4dd67c-171a-4764-a452-3196cb8df22d

  • navigationStyle: NavigationStyle.linear

https://github.com/user-attachments/assets/a8b735cd-d763-4cf5-a11e-37b55b5f848b

Package Rankings
Top 32.54% on Pub.dev
Related Projects