在 Flutter 中设置 BottomNavigationBar 样式

Style BottomNavigationBar in Flutter

我正在试用 Flutter,我正在尝试更改应用程序上 BottomNavigationBar 的颜色,但我所能实现的只是更改 BottomNavigationItem(图标和文本)的颜色。

这里是我声明我的 BottomNavigationBar:

class _BottomNavigationState extends State<BottomNavigationHolder>{

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: null,
      body: pages(),
      bottomNavigationBar:new BottomNavigationBar(
        items: <BottomNavigationBarItem>[
          new BottomNavigationBarItem(
              icon: const Icon(Icons.home),
              title: new Text("Home")
          ),
          new BottomNavigationBarItem(
              icon: const Icon(Icons.work),
              title: new Text("Self Help")
          ),
          new BottomNavigationBarItem(
              icon: const Icon(Icons.face),
              title: new Text("Profile")
          )
        ],
        currentIndex: index,
        onTap: (int i){setState((){index = i;});},
        fixedColor: Colors.white,
      ),
    );
  }

早些时候我以为我已经通过在我的主应用程序主题上将 canvasColor 编辑为绿色来解决这个问题,但它弄乱了整个应用程序的配色方案:

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
        canvasColor: Colors.green
      ),
      home: new FirstScreen(),
    );
  }
}

没有选项可以指定 BottomNavigationBar 的背景颜色,但可以更改 canvasColor。在不弄乱整个应用程序的情况下实现它的一种方法是将 BottomNavigationBar 包装在 Theme 中,并带有所需的 canvasColor.

示例:

  bottomNavigationBar: new Theme(
    data: Theme.of(context).copyWith(
        // sets the background color of the `BottomNavigationBar`
        canvasColor: Colors.green,
        // sets the active color of the `BottomNavigationBar` if `Brightness` is light
        primaryColor: Colors.red,
        textTheme: Theme
            .of(context)
            .textTheme
            .copyWith(caption: new TextStyle(color: Colors.yellow))), // sets the inactive color of the `BottomNavigationBar`
    child: new BottomNavigationBar(
      type: BottomNavigationBarType.fixed,
      currentIndex: 0,
      items: [
        new BottomNavigationBarItem(
          icon: new Icon(Icons.add),
          title: new Text("Add"),
        ),
        new BottomNavigationBarItem(
          icon: new Icon(Icons.delete),
          title: new Text("Delete"),
        )
      ],
    ),
  ),

希望对您有所帮助!

尝试将 BottomNavigationBar 包裹在 Container 中,然后设置其 color

示例:

@override
  Widget build(BuildContext context) {
    return Scaffold(
      body: pages(),
      bottomNavigationBar:new Container(
        color: Colors.green,
        child: BottomNavigationBar(
          items: <BottomNavigationBarItem>[
            BottomNavigationBarItem(
                icon: const Icon(Icons.home),
                title: Text("Home")
            ),
            BottomNavigationBarItem(
                icon: const Icon(Icons.work),
                title: Text("Self Help")
            ),
            BottomNavigationBarItem(
                icon: const Icon(Icons.face),
                title: Text("Profile")
            )
          ],
        currentIndex: index,
        onTap: (int i){setState((){index = i;});},
        fixedColor: Colors.white,
        ),
      );
    );
  };

只需将 backgroundColor 属性 添加到 BottomNavigationBar 小部件。

@override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: null,
      body: pages(),
      bottomNavigationBar:new BottomNavigationBar(
        items: <BottomNavigationBarItem>[
          new BottomNavigationBarItem(
              icon: const Icon(Icons.home),
              title: new Text("Home")
          ),
          new BottomNavigationBarItem(
              icon: const Icon(Icons.work),
              title: new Text("Self Help")
          ),
          new BottomNavigationBarItem(
              icon: const Icon(Icons.face),
              title: new Text("Profile")
          )
        ],
        currentIndex: index,
        onTap: (int i){setState((){index = i;});},
        fixedColor: Colors.white,
        backgroundColor: Colors.black45,
      ),
    );
  }

公认的答案并非完全错误。但是,BottomNavigationBar in-fact 的 属性 为 backgroundColor。根据文档

If type is BottomNavigationBarType.shifting and the itemss, have BottomNavigationBarItem.backgroundColor set, the item's backgroundColor will splash and overwrite this color.

这意味着 BottomNavigation 的 backgroundColor 将被个别项目的 backgroundColor 覆盖,因为默认类型是 BottomNavigationBarType.shifting

要解决此问题,只需将以下 属性 添加到已声明的 BottomNavigationbar 小部件中。

type: BottomNavigationBarType.fixed,

注意:但是,如果您想要移动效果,则必须为每个项目声明颜色,或者包装允许覆盖子小部件的小部件( s) 背景颜色。

即类似于 Container 小部件。

BottomNavigationBar 可以固定也可以移动(移动)。 如果有 3 个项目是固定的,并且更改为 4 个或更多项目的移位。我们可以通过设置 BottomNavigationBar.type 参数来覆盖此行为。

  • 固定BottomNavigationBar

    BottomNavigationBar(
      type: BottomNavigationBarType.fixed, // Fixed 
      backgroundColor: Colors.black, // <-- This works for fixed
      selectedItemColor: Colors.greenAccent,
      unselectedItemColor: Colors.grey,
      items: [
        BottomNavigationBarItem(
          icon: Icon(Icons.call),
          label: 'Call',
        ),
        BottomNavigationBarItem(
          icon: Icon(Icons.message),
          label: 'Message',
        ),
      ],
    )
    

  • 移位BottomNavigationBar:

    BottomNavigationBar(
      type: BottomNavigationBarType.shifting, // Shifting
      selectedItemColor: Colors.white,
      unselectedItemColor: Colors.grey,
      items: [
        BottomNavigationBarItem(
          icon: Icon(Icons.call),
          label: 'Call',
          backgroundColor: Colors.blue, // <-- This works for shifting
        ),
        BottomNavigationBarItem(
          icon: Icon(Icons.message),
          label: 'Message',
          backgroundColor: Colors.green, // <-- This works for shifting
        ),
      ],
    )
    

如果类型固定,可以通过将颜色设置为 backgroundColor 属性 来更改。

BottomNavigationBar(
          backgroundColor: Colors.red,
          type: BottomNavigationBarType.fixed,
          items: [
            BottomNavigationBarItem(
                icon:Icon(Icons.home, color: Color.fromARGB(255, 255, 255, 255)),
                title: new Text('Home'),),
            BottomNavigationBarItem(
                icon: Icon(Icons.work,color: Color.fromARGB(255, 255, 255, 255)),
                title: new Text('Self Help'),),
            BottomNavigationBarItem(
                icon:Icon(Icons.face, color: Color.fromARGB(255, 255, 255, 255)),
                title: new Text('Profile'),),
          ]
        )

如果类型发生变化,它将在 bottomNavigationBarItem 中使用颜色。

BottomNavigationBar(
          backgroundColor: Colors.red,
          type: BottomNavigationBarType.shifting,
          items: [
            BottomNavigationBarItem(
                icon:Icon(Icons.home, color: Color.fromARGB(255, 255, 255, 255)),
                title: new Text('Home'),
                backgroundColor: Colors.red),
            BottomNavigationBarItem(
                icon: Icon(Icons.work,color: Color.fromARGB(255, 255, 255, 255)),
                title: new Text('Self Help'),
                backgroundColor: Colors.blue),
            BottomNavigationBarItem(
                icon:Icon(Icons.face, color: Color.fromARGB(255, 255, 255, 255)),
                title: new Text('Profile'),
                backgroundColor: Colors.amber),
          ]

        )

您可以看到,即使我设置了 backgroundColor 属性,它也不会应用该颜色,BottomNavigationBarItem 小部件内的背景颜色将覆盖它。

来自 here

设置以下属性以更改背景已选择未选择颜色

bottomNavigationBar: BottomNavigationBar(
        backgroundColor: Colors.blue,
        selectedItemColor: Colors.black,
        unselectedItemColor: Colors.white,
        type: BottomNavigationBarType.fixed,
        ...
)

您目前可以直接从 Theme 为它们 BottomNavigationBar 设置样式,如下所示:

ThemeData(
    bottomNavigationBarTheme: BottomNavigationBarThemeData(
        backgroundColor: Colors.grey[900],
        elevation: 10,
        selectedLabelStyle: TextStyle(
            color: Color(0xFFA67926), fontFamily: 'Montserrat', fontSize: 14.0
        ),
        unselectedLabelStyle: TextStyle(
            color: Colors.grey[600], fontFamily: 'Montserrat', fontSize: 12.0
        ),
        selectedItemColor: Color(0xFFA67926),
        unselectedItemColor: Colors.grey[600],
        showUnselectedLabels: true,
    ),
)

title 已弃用。我们使用 label 代替。
对于label,我们可以使用相应的属性:selectedLabelStyle, unselectedLabelStyle
例如:

bottomNavigationBar: BottomNavigationBar(
          type: BottomNavigationBarType.fixed,
          selectedItemColor: Theme.of(context).accentColor,
          selectedFontSize: 0,
          unselectedFontSize: 0,
          iconSize: 22,
          elevation: 0,
          backgroundColor: Colors.transparent,
          selectedIconTheme: IconThemeData(size: 28),
          unselectedItemColor: Theme.of(context).focusColor.withOpacity(1),
          selectedLabelStyle: Theme.of(context).textTheme.bodyText1.merge(TextStyle(fontSize: 12)),
          unselectedLabelStyle: Theme.of(context).textTheme.button.merge(TextStyle(fontSize: 11)),
          showUnselectedLabels: true,
          currentIndex: widget.currentTabIdx,
          onTap: (int i) {
            this._selectTab(i);
          },
          showSelectedLabels: true,
          // this will be set when a new tab is tapped
          items: [
            BottomNavigationBarItem(
              icon: SvgPicture.asset(IMAGE_ASSETS_ICONS_HOME) ,
              activeIcon: SvgPicture.asset(IMAGE_ASSETS_ICONS_HOME, color: Theme.of(context).accentColor),
              label: 'Home',
            ),
            BottomNavigationBarItem(
                label: 'Categories',
              icon: SvgPicture.asset(IMAGE_ASSETS_ICONS_CATEGORY),
              activeIcon: SvgPicture.asset(IMAGE_ASSETS_ICONS_CATEGORY, color: Theme.of(context).accentColor) ,
            ),
            BottomNavigationBarItem(
              icon: SvgPicture.asset(IMAGE_ASSETS_ICONS_ORDER_HISTORY, ) ,
              activeIcon: SvgPicture.asset(IMAGE_ASSETS_ICONS_ORDER_HISTORY, color: Theme.of(context).accentColor ) ,
              label: 'Order History',
            ),
            BottomNavigationBarItem(
              icon: SvgPicture.asset(IMAGE_ASSETS_ICONS_CART,) ,
              activeIcon: SvgPicture.asset(IMAGE_ASSETS_ICONS_CART, color: Theme.of(context).accentColor) ,
              label: 'Cart',
            ),
          ],

只需按照下面给出的代码,根据您的要求进行定制。您只需要将 NavigationBar 的父级设置为 Theme 并设置 canvasColor 以更改背景颜色

      bottomNavigationBar: Theme(
    data: Theme.of(context).copyWith(
      canvasColor: kOrangeMaterialColor
    ),
    child: BottomNavigationBar(
      type: BottomNavigationBarType.shifting,
      currentIndex: _currentIndex,
      onTap: _onTapItem,

      items: [
        BottomNavigationBarItem(icon: Icon(Icons.home,
        color: kWhiteColor,),
        label: ''),
        BottomNavigationBarItem(icon: Icon(Icons.notifications,
        color: kWhiteColor,),
        label: ''),
        // BottomNavigationBarItem(icon: Icon(Icons.favorite_border,
        // color: kWhiteColor,),
       // label: ''),
        BottomNavigationBarItem(icon: Icon(Icons.account_circle,
        color: kWhiteColor,),
        label: ''),
        BottomNavigationBarItem(icon: Icon(Icons.settings,
        color: kWhiteColor,),
        label: ''),
      ],
    ),
  ),

使用

BottomNavigationBar (
backgroundColor: Colors.red,
)

如果不使用 material 小部件改变颜色。

Material(
child:
BottomNavigationBar (
backgroundColor: Colors.red,
),
)

您可以使用此代码:

BottomNavigationBar (
backgroundColor: Colors.red,
type: BottomNavigationBarType.fixed
)

或使用 Theme 小部件扭曲 BottomNavigation 并更改 canvasColor

Theme(
    data: Theme.of(context).copyWith(canvasColor: Colors.green),
    child: BottomNavigationBar(
      // add your code ...
        )
      ],
    ),
  ),

// 它会像这样的背景颜色

import 'package:flutter/material.dart';
import 'package:pedometer/widgets/const.dart';
import 'package:pedometer/widgets/const.dart';
import 'package:pedometer/widgets/const.dart';
import 'package:pedometer/widgets/icon.dart';

import 'dashbord.dart';

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

  @override
  State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}

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

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: _widgetOptions.elementAt(_selectedIndex),
      ),
      bottomNavigationBar: BottomNavigationBar(
         backgroundColor: const Color.fromARGB(255, 6, 17, 93),
         type: BottomNavigationBarType.fixed,
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
           // iconFun(path:Icons.home,context: context )
            icon: Icon(Icons.home,color: Colors.white,size: 35,),
            label: 'Home',
          //  backgroundColor: Colors.red,
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.auto_graph_outlined,color: Colors.white,size: 35),
            label: 'Business',
            backgroundColor: Colors.green,
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.health_and_safety,color: Colors.white,size: 35),
            label: 'School',
           // backgroundColor: Colors.purple,
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.settings,color: Colors.white,size: 35),
            label: 'Settings',
         //   backgroundColor: Colors.pink,
          ),
        ],
        currentIndex: _selectedIndex,
        selectedItemColor: Colors.white,
        onTap: _onItemTapped,
      ),
    );
  }
}