BottomNavigationBarItem 中的背景色

BottomNavigationBarItem background color in flutter

我需要像这张图片一样为选定的 BottomNavigationBarItem 设置背景色

以下是点击时更改背景的示例:

class _MyWidgetState extends State<MyWidget> {
  IconData selectedItem = Icons.dashboard;

  List<IconData> get itemsList => _items.keys;

  Map<IconData, String> _items = {
    Icons.home: 'Home',
    Icons.drive_eta: 'Delivery',
    Icons.shopping_basket: 'Products',
    Icons.mail: 'Messages'
  };

  @override
  Widget build(BuildContext context) {
    return BottomNavigationBar(
        onTap: (int index) {
          // todo something
          setState(() {
            selectedItem = itemsList[index];
          });
        },
        currentIndex: itemsList.indexOf(selectedItem),
        items: _items.entries.map((MapEntry<IconData, String> entry) {
          return BottomNavigationBarItem(
            icon: Icon(entry.key, color: Colors.white),
            backgroundColor: entry.key == selectedItem ? Colors.black : Colors.blueGrey,
            title: Text(entry.value),
          );
        }).toList());
  }
}

据我所知,使用 BottomNavigationBar 时无法更改选项卡的颜色。但是,我可以建议切换到 TabBar 吗?它看起来像这样:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  static const String _title = 'Flutter Code Sample';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: _title,
      home: MyStatefulWidget(),
    );
  }
}

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

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

class _MyStatefulWidgetState extends State<MyStatefulWidget>
    with SingleTickerProviderStateMixin {
  TabController _tabController;

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

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: TabBarView(
        controller: _tabController,
        children: <Widget>[
          Scaffold(appBar: AppBar(title: Text('First'))),
          Scaffold(appBar: AppBar(title: Text('Second'))),
          Scaffold(appBar: AppBar(title: Text('Third'))),
        ],
      ),
      bottomNavigationBar: BottomAppBar(
        child: Container(
          color: Colors.blue,
          child: TabBar(
            indicator: BoxDecoration(color: Colors.redAccent),
            tabs: <Widget>[
              Tab(child: Text("Stuff", style: TextStyle(color: Colors.white))),
              Tab(child: Text("Things", style: TextStyle(color: Colors.white))),
              Tab(child: Text("Items", style: TextStyle(color: Colors.white))),
            ],
            controller: _tabController,
          ),
        ),
      ),
    );
  }
}

结果:

这是一个非常简单的例子,但它展示了它的要点。

无法更改 BottomNavigationBar 中所选项目的背景,因为这不符合设计准则。

如果您仍想以这种方式使用它,请按照 BottomNavigationBar class 中给出的示例,这里有一个解决方法:

final _selectedItemColor = Colors.white;
final _unselectedItemColor = Colors.white30;
final _selectedBgColor = Colors.indigo;
final _unselectedBgColor = Colors.blue;
int _selectedIndex = 0;
static const TextStyle optionStyle =
    TextStyle(fontSize: 30, fontWeight: FontWeight.bold);
static const List<Widget> _widgetOptions = <Widget>[
  Text(
    'Index 0: Home',
    style: optionStyle,
  ),
  Text(
    'Index 1: Business',
    style: optionStyle,
  ),
  Text(
    'Index 2: School',
    style: optionStyle,
  ),
];

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

Color _getBgColor(int index) =>
    _selectedIndex == index ? _selectedBgColor : _unselectedBgColor;

Color _getItemColor(int index) =>
    _selectedIndex == index ? _selectedItemColor : _unselectedItemColor;

Widget _buildIcon(IconData iconData, String text, int index) => Container(
      width: double.infinity,
      height: kBottomNavigationBarHeight,
      child: Material(
        color: _getBgColor(index),
        child: InkWell(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Icon(iconData),
              Text(text,
                  style: TextStyle(fontSize: 12, color: _getItemColor(index))),
            ],
          ),
          onTap: () => _onItemTapped(index),
        ),
      ),
    );

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: const Text('BottomNavigationBar Sample'),
    ),
    body: Center(
      child: _widgetOptions.elementAt(_selectedIndex),
    ),
    bottomNavigationBar: BottomNavigationBar(
      selectedFontSize: 0,
      items: <BottomNavigationBarItem>[
        BottomNavigationBarItem(
          icon: _buildIcon(Icons.home, 'Home', 0),
          title: SizedBox.shrink(),
        ),
        BottomNavigationBarItem(
          icon: _buildIcon(Icons.business, 'Business', 1),
          title: SizedBox.shrink(),
        ),
        BottomNavigationBarItem(
          icon: _buildIcon(Icons.school, 'School', 2),
          title: SizedBox.shrink(),
        ),
      ],
      currentIndex: _selectedIndex,
      selectedItemColor: _selectedItemColor,
      unselectedItemColor: _unselectedItemColor,
    ),
  );
}

结果: