Tushar Rai
Tushar Rai

Reputation: 2519

How to set border radius to bottom app bar in a flutter app?

I want to set the borderRadius to an Bottom Navigation App Bar as its shown in the image. I have tried to put Bottom Navigation App Bar to a ClipRRect borderRadius and in a Container decoration but it didn't worked. So how can I apply the topLeft, and topRight border radius to my bottom navigation bar. Kindly help to let me know how can I do it?

enter image description here

main.dart

    void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Food Ordering',
      theme: ThemeData(primarySwatch: Colors.blue, primaryColor: Colors.white),
      home: MyStatefulWidget(),
      routes: <String, WidgetBuilder>{
        '/detail-page': (BuildContext context) => MyDetailPage(),
      },
    );
  }
}

class MyStatefulWidget extends StatefulWidget {
  MyStatefulWidget({Key key}) : super(key: key);

  @override
  _MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  int _selectedIndex = 0;
  static const TextStyle optionStyle =
      TextStyle(fontSize: 30, fontWeight: FontWeight.bold);
  static List<Widget> _widgetOptions = <Widget>[
    HomePage(),
    HomePage(),
    HomePage(),
    HomePage(),
  ];

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: _widgetOptions.elementAt(_selectedIndex),
      ),
      bottomNavigationBar: BottomNavigationBar(
          items: <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: Image.asset('assets/icon-home.png'),
              title: Text('Home'),
            ),
            BottomNavigationBarItem(
              icon: Image.asset('assets/icon-mentors.png'),
              title: Text('Mentors'),
            ),
            BottomNavigationBarItem(
              icon: Image.asset('assets/icon-messages.png'),
              title: Text('Messages'),
            ),
            BottomNavigationBarItem(
              icon: Image.asset('assets/icon-settings.png'),
              title: Text('Settings'),
            ),
          ],
          currentIndex: _selectedIndex,
          selectedItemColor: Colors.blue,
          onTap: _onItemTapped),
    );
  }
}

Upvotes: 17

Views: 32699

Answers (4)

Ajil O.
Ajil O.

Reputation: 6892

EDIT

Scaffold now has a property called extendBody which can be used to extend the body below a bottomBar. From the documentation,

If true, and bottomNavigationBar or persistentFooterButtons is specified, then the body extends to the bottom of the Scaffold, instead of only extending to the top of the bottomNavigationBar or the persistentFooterButtons.

This means that all you need to do is

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Some Text'),
      ),
      body: bodyContent,
      extendBody: true,
      bottomNavigationBar: bottomNavigationBar,
    );
  }

  Widget get bodyContent {
    return Container(color: Colors.red);
  }

  Widget get bottomNavigationBar {
    return ClipRRect(
      borderRadius: const BorderRadius.only(
        topRight: Radius.circular(40),
        topLeft: Radius.circular(40),
      ),
      child: BottomNavigationBar(
        items: const [
          BottomNavigationBarItem(icon: Icon(Icons.home), label: '1'),
          BottomNavigationBarItem(icon: Icon(Icons.usb), label: '2'),
          BottomNavigationBarItem(
              icon: Icon(Icons.assignment_ind), label: '3'),
          BottomNavigationBarItem(
              icon: Icon(Icons.multiline_chart), label: '4'),
        ],
        unselectedItemColor: Colors.grey,
        selectedItemColor: Colors.black,
        showUnselectedLabels: true,
      ),
    );
  }
}

OUTDATED

Put it inside a stack. Don't add the Bottom Navigation Bar to the scaffold directly.

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Some Text'),
      ),
      body: Stack(
        children: <Widget>[
          bodyContent,
          Positioned(
            left: 0,
            right: 0,
            bottom: 0,
            child: bottomNavigationBar,
          ),
        ],
      ),
    );
  }

  Widget get bodyContent {
    return Container(color: Colors.red);
  }

  Widget get bottomNavigationBar {
    return ClipRRect(
      borderRadius: BorderRadius.only(
        topRight: Radius.circular(40),
        topLeft: Radius.circular(40),
      ),
      child: BottomNavigationBar(
        items: [
          BottomNavigationBarItem(icon: Icon(Icons.home), title: Text('1')),
          BottomNavigationBarItem(icon: Icon(Icons.usb), title: Text('2')),
          BottomNavigationBarItem(
              icon: Icon(Icons.assignment_ind), title: Text('3')),
          BottomNavigationBarItem(
              icon: Icon(Icons.multiline_chart), title: Text('4')),
        ],
        unselectedItemColor: Colors.grey,
        selectedItemColor: Colors.black,
        showUnselectedLabels: true,
      ),
    );
  }
}

Upvotes: 37

Enamul Haque
Enamul Haque

Reputation: 5053

You may user bellow like .

  1. My bottomNavigationBar image is look like enter image description here

2. here is thecode

        import 'package:flutter/material.dart';

    class BottomTab extends StatefulWidget {
      @override
      State<StatefulWidget> createState() {
        return _BottomTab();
      }
    }

    class _BottomTab extends State<BottomTab> {
      int _selectedTabIndex = 0;

      List _pages = [
        Text("Home"),
        Text("Order"),
        Text("Notfication"),
        Text("More"),
      ];

      _changeIndex(int index) {
        setState(() {
          _selectedTabIndex = index;
          print("index..." + index.toString());
        });
      }

      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('bottom nav bar'),
          ),
          body: Center(child: _pages[_selectedTabIndex]),
          bottomNavigationBar: bottomNavigationBar,
        );
      }

      Widget get bottomNavigationBar {
        return Container(
            decoration: BoxDecoration(
              borderRadius: BorderRadius.only(
                  topRight: Radius.circular(30), topLeft: Radius.circular(30)),
              boxShadow: [
                BoxShadow(color: Colors.black38, spreadRadius: 0, blurRadius: 10),
              ],
            ),
            child: ClipRRect(
              borderRadius: BorderRadius.only(
                topLeft: Radius.circular(30.0),
                topRight: Radius.circular(30.0),
              ),
              child: BottomNavigationBar(
                currentIndex: _selectedTabIndex,
                onTap: _changeIndex,
                type: BottomNavigationBarType.fixed,
                selectedFontSize: 12,
                unselectedFontSize: 12,
                selectedItemColor: Colors.amber[800],
                unselectedItemColor: Colors.grey[500],
                showUnselectedLabels: true,
                items: <BottomNavigationBarItem>[
                  BottomNavigationBarItem(
                    icon: new Icon(Icons.home),
                    title: new Text('Home'),
                  ),
                  BottomNavigationBarItem(
                    icon: new Icon(Icons.shopping_cart_outlined),
                    title: new Text('Order'),
                  ),
                  BottomNavigationBarItem(
                    icon: new Icon(Icons.mail),
                    title: new Text('Messages'),
                  ),
                  BottomNavigationBarItem(
                      icon: Icon(Icons.more_horiz_rounded), title: Text('More')),
                ],
              ),
            ));
      }
    }

Upvotes: 7

Salman
Salman

Reputation: 21

Just include the BottomNavigationBar inside the body, inside a circular border container. Like this (See the picture attached!)

    Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
      body: Container(
          decoration: BoxDecoration(
              image: DecorationImage(
                  image: new AssetImage("assets/images/background.jpg"),
                  fit: BoxFit.cover)),
          child: Stack(
            alignment: Alignment.bottomCenter,
            children: <Widget>[
              Expanded(
                child: Column(
                  children: <Widget>[
                    Expanded(child: _children[_currentIndex]),
                  ],
                ),
              ),
              Container(
                decoration: BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.only(
                      topLeft: Radius.circular(20),
                      topRight: Radius.circular(20),
                      bottomLeft: Radius.circular(0),
                      bottomRight: Radius.circular(0)),
                  boxShadow: [
                    BoxShadow(
                        offset: Offset(0.0, 1.00), //(x,y)
                        blurRadius: 4.00,
                        color: Colors.grey,
                        spreadRadius: 1.00),
                  ],
                ),
                height: 70,
                child: ClipRRect(
                    clipBehavior: Clip.hardEdge,
                    borderRadius: BorderRadius.only(
                        topLeft: Radius.circular(25),
                        topRight: Radius.circular(25),
                        bottomLeft: Radius.circular(0),
                        bottomRight: Radius.circular(0)),
                    child: Container(
                      child: BottomNavigationBar(
                        backgroundColor: Color.fromRGBO(255, 255, 255, 50),
                        showSelectedLabels: false,
                        showUnselectedLabels: false,
                        onTap: onTabTapped,
                        // new
                        currentIndex: _currentIndex,
                        // new
                        items: [
                          new BottomNavigationBarItem(
                            icon: Icon(
                              Icons.phone,
                              size: 30,
                            ),
                            title: Text('Calls'),
                          ),
                          new BottomNavigationBarItem(
                            icon: Icon(
                              Icons.mail,
                              size: 30,
                            ),
                            title: Text('Messages'),
                          ),
                          new BottomNavigationBarItem(
                              icon: Icon(
                                Icons.person,
                                size: 30,
                              ),
                              title: Text('Profile'))
                        ],
                      ),
                    )),
              )
            ],
          )),
    ));
  }

Upvotes: 2

SHAFI ul BARI
SHAFI ul BARI

Reputation: 191

Alternatively, if your goal is to only put a borderRadius you can just use ClipRRect and apply your desired borderRadius to it. Here is my implementation of the solution:


  ClipRRect _getBtmNavBar() {
    return ClipRRect(
      borderRadius: BorderRadius.only(
        topLeft: Radius.circular(25),
        topRight: Radius.circular(25),
      ),
      child: BottomNavigationBar(
        currentIndex: _selectedIndex,
        onTap: _onTabTapped,
        selectedLabelStyle: TextStyle(
          color: Colors.black87,
          fontSize: 16,
        ),
        iconSize: 35,
        selectedItemColor: Colors.white,
        unselectedItemColor: Colors.black54,
        items: <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            backgroundColor: kBottomNavBarBgColor,
            icon: Icon(Icons.home),
            title: Text('Home'),
          ),
// more BottomNavigationBarItem() goes here.

Then plug it directly into your bottomNavigationBar

Code Example:

return Scaffold(
// more Scaffold code goes here

//bottom navigationBar
      bottomNavigationBar: _getBtmNavBar(),
);

Upvotes: 9

Related Questions