如何创建这种类型的底部导航?

How to create this type of Bottom Navigation?

我正在尝试制作一个看起来完全像这样的底部导航栏。由于我只是学习 flutter 的初学者,我遇到了很多问题,其中之一就是找不到图标,所以我决定使用其他类似的可用图标。现在我只是对自己的代码感到困惑。 这就是我想要的:

这是我的底部导航栏的样子:

这是我的代码:

Scaffold(bottomNavigationBar: 

    Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: [
        Container(
          height: 50,
          width: MediaQuery.of(context).size.width / 5,
          decoration: BoxDecoration(color:Color(0xfffed307)),
          child: Column(
            children: [
              Icon(Icons.store_mall_directory_outlined),
              Text('My Page')
            ],
          ),
        ),
        Container(
          height: 50,
          width: MediaQuery.of(context).size.width / 5,
          decoration: BoxDecoration(color: Color(0xfffed307)),
          child: Column(
            children: [Icon(Icons.apps), Text('Election')],
          ),
        ),
        Container(
          height: 50,
          width: MediaQuery.of(context).size.width / 5,
          decoration: BoxDecoration(color: Color(0xfffed307)),
          child: Image.asset('images/scan_icon.png'),
        ),
        Container(
          height: 50,
          width: MediaQuery.of(context).size.width / 5,
          decoration: BoxDecoration(color: Color(0xfffed307)),
          child: Column(
            children: [Icon(Icons.apps), Text('Add Election')],
          ),
        ),
        Expanded(
          child: Container(
            height: 50,
            width: MediaQuery.of(context).size.width / 5,
            decoration: BoxDecoration(color: Color(0xfffed307)),
            child: Column(
              children: [Icon(Icons.groups_outlined), Text('Customer')],
            ),
          ),
        ),
      ],
    )
    ,);

您可以使用 floatingActionButton 作为扫描图标并使用 floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,

使用 Flutter,制作这种 UI 很容易))如果你真的在 Stack Widget 中使用 Positioned Widget想使用 Scaffold 小部件的 bottomNavigationBar 属性 制作这个 UI。

结果UI

复制粘贴下面的代码看看效果:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // Try running your application with "flutter run". You'll see the
        // application has a blue toolbar. Then, without quitting the app, try
        // changing the primarySwatch below to Colors.green and then invoke
        // "hot reload" (press "r" in the console where you ran "flutter run",
        // or simply save your changes to "hot reload" in a Flutter IDE).
        // Notice that the counter didn't reset back to zero; the application
        // is not restarted.
        primarySwatch: Colors.blue,
      ),
      home: MyScreen(),
    );
  }
}

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

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

class _MyScreenState extends State<MyScreen> {
  late List<Widget> _screens;
  int currentIndex = 0;
  @override
  void initState() {
    super.initState();
    _screens = [
      TestScreen(title: '1st Screen'),
      TestScreen(title: '2nd Screen'),
      TestScreen(title: '3rd Screen'),
      TestScreen(title: '4th Screen'),
      TestScreen(title: '5th Screen'),
    ];
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: IndexedStack(
        index: currentIndex,
        children: _screens,
      ),
      bottomNavigationBar: BottomBar(
        selectedIndex: currentIndex,
        children: [
          BottomBarItem(icon: Icons.home),
          BottomBarItem(icon: Icons.search),
          BottomBarItem(icon: Icons.favorite),
          BottomBarItem(icon: Icons.person),
        ],
        onMainPressed: () {
          setState(() {
            currentIndex = 4;
          });
        },
        onPressed: (index) {
          setState(() {
            currentIndex = index;
          });
        },
      ),
    );
  }
}

class BottomBarItem {
  BottomBarItem({required this.icon});

  IconData icon;
}

class BottomBar extends StatelessWidget {
  final List<BottomBarItem> children;
  final Function? onPressed;
  final Function? onMainPressed;
  final selectedIndex;

  BottomBar({
    this.children = const [],
    this.onPressed,
    this.onMainPressed,
    this.selectedIndex,
  });

  @override
  Widget build(BuildContext context) {
    Size size = MediaQuery.of(context).size;
    return Container(
      color: Colors.grey[100],
      child: SafeArea(
        bottom: true,
        child: Container(
          height: 60,
          decoration: BoxDecoration(
            color: Colors.grey[100],
            boxShadow: [
              BoxShadow(
                color: Colors.grey,
                blurRadius: 8.0,
                offset: Offset(
                  0.0, // horizontal, move right 10
                  -6.0, // vertical, move down 10
                ),
              ),
            ],
          ),
          child: Stack(
            clipBehavior: Clip.none,
            children: [
              Row(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                mainAxisAlignment: MainAxisAlignment.center,
                children: children.map<Widget>(
                  (item) {
                    int index = children.indexOf(item);
                    bool isSelected = selectedIndex == index;
                    return Expanded(
                      child: Material(
                        color: Colors.transparent,
                        child: InkWell(
                          onTap: () {
                            onPressed!(index);
                          },
                          child: Padding(
                            padding: EdgeInsets.zero,
                            child: Icon(
                              item.icon,
                              size: isSelected ? 35 : 30,
                              color: isSelected ? Colors.blue : Colors.grey,
                            ),
                          ),
                        ),
                      ),
                    );
                  },
                ).toList()
                  ..insert(2, SizedBox(width: 80)),
              ),
              Positioned(
                top: -14,
                width: size.width,
                child: Center(
                  child: Container(
                    height: 60,
                    width: 60,
                    child: ClipOval(
                      child: Material(
                        color: selectedIndex == 4 ? Colors.blue : Colors.grey,
                        child: InkWell(
                          onTap: () {
                            onMainPressed!();
                          },
                          child: Center(
                            child: Icon(
                              Icons.adb,
                              size: 27,
                              color: Colors.white,
                            ),
                          ),
                        ),
                      ),
                    ),
                    decoration: BoxDecoration(
                      shape: BoxShape.circle,
                      boxShadow: [
                        BoxShadow(
                          color: Colors.grey,
                          blurRadius: 6.0,
                        ),
                      ],
                    ),
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class TestScreen extends StatelessWidget {
  final String title;
  const TestScreen({required this.title, Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
          child: Container(
        child: Text(title),
      )),
    );
  }
}