创建自定义 Flutter 底部导航栏

Creating a Custom Flutter Bottom Navigation bar

我试图寻找一种自定义底部导航栏的方法,如图所示。

我还是看不清楚。当它被选中但没有标签时,我可以用它周围的蓝色框突出显示图标。 有没有办法实现这一目标或采取不同的方法? 如果有人可以帮助提供代码片段,我们将很高兴。

试试下面的代码希望对你有帮助。参考 floating_bottom_navigation_barhere refer this package also list of BottonNavigation Packages here

Scaffold(
    extendBody: true,
     body: Center(
    child: Text(
      "index: $_index",
      style: TextStyle(
        fontSize: 52,
      ),
    ),
  ),
  bottomNavigationBar: FloatingNavbar(
    backgroundColor: Colors.transparent,
    selectedBackgroundColor: Colors.indigo,
    unselectedItemColor: Colors.grey,
    selectedItemColor: Colors.white,
    onTap: (int val) {
      setState(() {
        _index = val;
      });
    },
    currentIndex: _index,
    items: [
      FloatingNavbarItem(
        icon: Icons.home,
        title: 'Home',
      ),
      FloatingNavbarItem(
        icon: Icons.explore,
        title: 'Explore',
      ),
      FloatingNavbarItem(
        icon: Icons.chat_bubble_outline,
        title: 'Chats',
      ),
      FloatingNavbarItem(
        icon: Icons.settings,
        title: 'Settings',
      ),
    ],
  ),
);

你的结果屏幕像->

这是我的简单解决方案,没有任何第三方包,您可以自定义此小部件,我相信还有很大的改进空间。希望这能让您了解如何进一步发展。

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  static const String _title = 'Flutter Code Sample';

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

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

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

class _MyStatefulWidgetState extends State<MyStatefulWidget>
    with SingleTickerProviderStateMixin {
  int _selectedIndex = 0;
  static const TextStyle optionStyle =
      TextStyle(fontSize: 30, fontWeight: FontWeight.bold);
  static const List<Widget> _bodyView = <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;
    });
  }

  late TabController _tabController;

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

  Widget _tabItem(Widget child, String label, {bool isSelected = false}) {
    return AnimatedContainer(
        margin: EdgeInsets.all(8),
        alignment: Alignment.center,
        duration: const Duration(milliseconds: 500),
        decoration: !isSelected
            ? null
            : BoxDecoration(
                borderRadius: BorderRadius.circular(10),
                color: Colors.black,
              ),
        padding: const EdgeInsets.all(10),
        child: Column(
          children: [
            child,
            Text(label, style: TextStyle(fontSize: 8)),
          ],
        ));
  }

  final List<String> _labels = ['Home', 'maps', 'camera'];

  @override
  Widget build(BuildContext context) {
    List<Widget> _icons = const [
      Icon(Icons.home_outlined),
      Icon(Icons.explore_outlined),
      Icon(Icons.camera_alt_outlined)
    ];

    return Scaffold(
      appBar: AppBar(
        title: const Text('BottomNavigationBar Sample'),
      ),
      body: Center(
        child: _bodyView.elementAt(_selectedIndex),
      ),
      bottomNavigationBar: Container(
        height: 100,
        padding: const EdgeInsets.all(12),
        child: ClipRRect(
          borderRadius: BorderRadius.circular(50.0),
          child: Container(
            color: Colors.teal.withOpacity(0.1),
            child: TabBar(
                onTap: (x) {
                  setState(() {
                    _selectedIndex = x;
                  });
                },
                labelColor: Colors.white,
                unselectedLabelColor: Colors.blueGrey,
                indicator: const UnderlineTabIndicator(
                  borderSide: BorderSide.none,
                ),
                tabs: [
                  for (int i = 0; i < _icons.length; i++)
                    _tabItem(
                      _icons[i],
                      _labels[i],
                      isSelected: i == _selectedIndex,
                    ),
                ],
                controller: _tabController),
          ),
        ),
      ),
    );
  }
}