美文网首页
【Flutter】自己实现底部凸起导航栏

【Flutter】自己实现底部凸起导航栏

作者: 峰豆豆 | 来源:发表于2019-11-05 15:44 被阅读0次

    最近在项目中,UI设计需要实现一个底部凸起的导航栏,一顿摸索,发现Flutter默认的导航栏就可以实现,好开心,一顿ctrl+c,ctrl+v之后,发现,what Fxxk,为什么底部还留出了一块,后来明白,Flutter原生的会默认在底部流出文字的位置,及时设置了也没有用。so,自己来。。。(新手小白,大佬勿喷)

    话不多说,有图有真相


    [图片上传中...(截屏2019-11-0515.21.04.png-98996f-1572939829473-0)]
    截屏2019-11-0515.21.04.png

    1.首先创建了4个page

     List<StatefulWidget> _pageList = [
        TaskPage(),
        WorkBenchPage(),
        MessagePage(),
        MePage()
      ];
      int lastTime = 0; // 点击后退按钮两次退出应用
      PageController pageController;
      int _currentIndex = 0;// 当前界面位置
    

    2.定义tab的点击事件,和page的切换

    void onPageChanged(int value) {
        setState(() {
          this._currentIndex = value;
        });
      }
    
      void onTap(int value) {
        setState(() {
          this._currentIndex = value;
        });
      }
    

    3.通过stack和Align实现底部凸起导航

    @override
      Widget build(BuildContext context) {
        return Container(
          color: Colors.white,
          child: WillPopScope(
              child: SafeArea(
                top: false,
                child: Scaffold(
                  body: this._pageList[_currentIndex],
                  bottomNavigationBar: Container(
                    height: 80,
                    child: Stack(
                      children: <Widget>[
                        Align(
                          alignment: Alignment.bottomCenter,
                          child: Container(
                            color: Colors.white,
                            height: 60,
                            child: Padding(
                              padding: new EdgeInsets.fromLTRB(0, 6, 0, 6),
                              child: Flex(
                                direction: Axis.horizontal,
                                mainAxisSize: MainAxisSize.max,
                                mainAxisAlignment: MainAxisAlignment.spaceAround,
                                children: <Widget>[
                                  Expanded(
                                    flex: 1,
                                    child: GestureDetector(
                                        onTap: () {
                                          onTap(0);
                                        },
                                        child: Column(
                                          mainAxisSize: MainAxisSize.min,
                                          children: <Widget>[
                                            Image.asset(
                                              _currentIndex == 0
                                                  ? "images/ic_tab_task_1.png"
                                                  : "images/ic_tab_task_0.png",
                                              width: _currentIndex == 0 ? 25 : 20,
                                              height: _currentIndex == 0 ? 25 : 20,
                                            ),
                                            Text("一",
                                                style: TextStyle(
                                                    color: _currentIndex == 0
                                                        ? Colors.blue
                                                        : Colors.grey))
                                          ],
                                        )),
                                  ),
                                  Expanded(
                                    flex: 1,
                                    child: GestureDetector(
                                        onTap: () {
                                          onTap(1);
                                        },
                                        child: Column(
                                          mainAxisSize: MainAxisSize.min,
                                          children: <Widget>[
                                            Image.asset(
                                              _currentIndex == 1
                                                  ? "images/ic_tab_workbench_1.png"
                                                  : "images/ic_tab_workbench_0.png",
                                              width: _currentIndex == 1 ? 25 : 20,
                                              height: _currentIndex == 1 ? 25 : 20,
                                            ),
                                            Text("一",
                                                style: TextStyle(
                                                    color: _currentIndex == 1
                                                        ? Colors.blue
                                                        : Colors.grey))
                                          ],
                                        )),
                                  ),
                                  Expanded(
                                    flex: 1,
                                    child: Column(
                                      mainAxisSize: MainAxisSize.min,
                                      children: <Widget>[],
                                    ),
                                  ),
                                  Expanded(
                                    flex: 1,
                                    child: GestureDetector(
                                        onTap: () {
                                          onTap(2);
                                        },
                                        child: Column(
                                          mainAxisSize: MainAxisSize.min,
                                          children: <Widget>[
                                            Image.asset(
                                              _currentIndex == 2
                                                  ? "images/ic_tab_message_1.png"
                                                  : "images/ic_tab_message_0.png",
                                              width: _currentIndex == 2 ? 25 : 20,
                                              height: _currentIndex == 2 ? 25 : 20,
                                            ),
                                            Text("一",
                                                style: TextStyle(
                                                    color: _currentIndex == 2
                                                        ? Colors.blue
                                                        : Colors.grey))
                                          ],
                                        )),
                                  ),
                                  Expanded(
                                    flex: 1,
                                    child: GestureDetector(
                                        onTap: () {
                                          onTap(3);
                                        },
                                        child: Column(
                                          mainAxisSize: MainAxisSize.min,
                                          children: <Widget>[
                                            Image.asset(
                                              _currentIndex == 3
                                                  ? "images/ic_tab_me_1.png"
                                                  : "images/ic_tab_me_0.png",
                                              width: _currentIndex == 3 ? 25 : 20,
                                              height: _currentIndex == 3 ? 25 : 20,
                                            ),
                                            Text("一",
                                                style: TextStyle(
                                                    color: _currentIndex == 3
                                                        ? Colors.blue
                                                        : Colors.grey))
                                          ],
                                        )),
                                  )
                                ],
                              ),
                            ),
                          ),
                        ),
                        // 这个就是悬浮出来的按钮
                        Align(
                            alignment: Alignment.bottomCenter,
                            child: Padding(
                              padding: const EdgeInsets.only(bottom: 10.0),
                              child: GestureDetector(
                                child: Container(
                                  decoration: BoxDecoration(
                                    color: Colors.white,
                                    shape: BoxShape.circle,
                                  ),
                                  padding: new EdgeInsets.all(3),
                                  child: Image.asset(
                                    "images/ic_tab_add.png",
                                    width: 100.0,
                                    height: 100.0,
                                  ),
                                ),
                                onTap: () {
                                  // 点击凸起按钮后,出现一个带动画的dialog
                                  _animationController = AnimationController(
                                      duration: const Duration(milliseconds: 500),
                                      vsync: this);
                                  _animationController.forward();
                                  MoreTabDialog.show(context,
                                      callBack: this,
                                      animationController: _animationController);
                                },
                              ),
                            )),
                      ],
                    ),
                  ),
                ),
              ),
              onWillPop: () {
                // 点击后退退出应用
                int newTime = DateTime.now().millisecondsSinceEpoch;
                int result = newTime - lastTime;
                lastTime = newTime;
                if (result > 2000) {
                  Fluttertoast.showToast(msg: "再按一次退出");
                } else {
                  SystemNavigator.pop();
                }
                return null;
              }),
        );
    

    完整代码

    1.首页

    class _ManagementMainPageState extends State<ManagementMainPage>
        with TickerProviderStateMixin
        implements MoreTabDialogCallBack {
    
      List<StatefulWidget> _pageList = [
        TaskPage(),
        WorkBenchPage(),
        MessagePage(),
        MePage()
      ];
      int lastTime = 0;
      PageController pageController;
      int _currentIndex = 0;
    
      AnimationController _animationController;
    
      @override
      void initState() {
        pageController = PageController(initialPage: this._currentIndex);
        super.initState();
      }
    
      @override
      void dispose() {
        _animationController.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return Container(
          color: Colors.white,
          child: WillPopScope(
              child: SafeArea(
                top: false,
                child: Scaffold(
                  body: this._pageList[_currentIndex],
                  bottomNavigationBar: Container(
                    height: 80,
                    child: Stack(
                      children: <Widget>[
                        Align(
                          alignment: Alignment.bottomCenter,
                          child: Container(
                            color: Colors.white,
                            height: 60,
                            child: Padding(
                              padding: new EdgeInsets.fromLTRB(0, 6, 0, 6),
                              child: Flex(
                                direction: Axis.horizontal,
                                mainAxisSize: MainAxisSize.max,
                                mainAxisAlignment: MainAxisAlignment.spaceAround,
                                children: <Widget>[
                                  Expanded(
                                    flex: 1,
                                    child: GestureDetector(
                                        onTap: () {
                                          onTap(0);
                                        },
                                        child: Column(
                                          mainAxisSize: MainAxisSize.min,
                                          children: <Widget>[
                                            Image.asset(
                                              _currentIndex == 0
                                                  ? "images/ic_tab_task_1.png"
                                                  : "images/ic_tab_task_0.png",
                                              width: _currentIndex == 0 ? 25 : 20,
                                              height: _currentIndex == 0 ? 25 : 20,
                                            ),
                                            Text("一",
                                                style: TextStyle(
                                                    color: _currentIndex == 0
                                                        ? Colors.blue
                                                        : Colors.grey))
                                          ],
                                        )),
                                  ),
                                  Expanded(
                                    flex: 1,
                                    child: GestureDetector(
                                        onTap: () {
                                          onTap(1);
                                        },
                                        child: Column(
                                          mainAxisSize: MainAxisSize.min,
                                          children: <Widget>[
                                            Image.asset(
                                              _currentIndex == 1
                                                  ? "images/ic_tab_workbench_1.png"
                                                  : "images/ic_tab_workbench_0.png",
                                              width: _currentIndex == 1 ? 25 : 20,
                                              height: _currentIndex == 1 ? 25 : 20,
                                            ),
                                            Text("一",
                                                style: TextStyle(
                                                    color: _currentIndex == 1
                                                        ? Colors.blue
                                                        : Colors.grey))
                                          ],
                                        )),
                                  ),
                                  Expanded(
                                    flex: 1,
                                    child: Column(
                                      mainAxisSize: MainAxisSize.min,
                                      children: <Widget>[],
                                    ),
                                  ),
                                  Expanded(
                                    flex: 1,
                                    child: GestureDetector(
                                        onTap: () {
                                          onTap(2);
                                        },
                                        child: Column(
                                          mainAxisSize: MainAxisSize.min,
                                          children: <Widget>[
                                            Image.asset(
                                              _currentIndex == 2
                                                  ? "images/ic_tab_message_1.png"
                                                  : "images/ic_tab_message_0.png",
                                              width: _currentIndex == 2 ? 25 : 20,
                                              height: _currentIndex == 2 ? 25 : 20,
                                            ),
                                            Text("一",
                                                style: TextStyle(
                                                    color: _currentIndex == 2
                                                        ? Colors.blue
                                                        : Colors.grey))
                                          ],
                                        )),
                                  ),
                                  Expanded(
                                    flex: 1,
                                    child: GestureDetector(
                                        onTap: () {
                                          onTap(3);
                                        },
                                        child: Column(
                                          mainAxisSize: MainAxisSize.min,
                                          children: <Widget>[
                                            Image.asset(
                                              _currentIndex == 3
                                                  ? "images/ic_tab_me_1.png"
                                                  : "images/ic_tab_me_0.png",
                                              width: _currentIndex == 3 ? 25 : 20,
                                              height: _currentIndex == 3 ? 25 : 20,
                                            ),
                                            Text("一",
                                                style: TextStyle(
                                                    color: _currentIndex == 3
                                                        ? Colors.blue
                                                        : Colors.grey))
                                          ],
                                        )),
                                  )
                                ],
                              ),
                            ),
                          ),
                        ),
                        Align(
                            alignment: Alignment.bottomCenter,
                            child: Padding(
                              padding: const EdgeInsets.only(bottom: 10.0),
                              child: GestureDetector(
                                child: Container(
                                  decoration: BoxDecoration(
                                    color: Colors.white,
                                    shape: BoxShape.circle,
                                  ),
                                  padding: new EdgeInsets.all(3),
                                  child: Image.asset(
                                    "images/ic_tab_add.png",
                                    width: 100.0,
                                    height: 100.0,
                                  ),
                                ),
                                onTap: () {
                                  _animationController = AnimationController(
                                      duration: const Duration(milliseconds: 500),
                                      vsync: this);
                                  _animationController.forward();
                                  MoreTabDialog.show(context,
                                      callBack: this,
                                      animationController: _animationController);
                                },
                              ),
                            )),
                      ],
                    ),
                  ),
                ),
              ),
              onWillPop: () {
                int newTime = DateTime.now().millisecondsSinceEpoch;
                int result = newTime - lastTime;
                lastTime = newTime;
                if (result > 2000) {
                  Fluttertoast.showToast(msg: "再按一次退出");
                } else {
                  SystemNavigator.pop();
                }
                return null;
              }),
        );
      }
    
      void onPageChanged(int value) {
        setState(() {
          this._currentIndex = value;
        });
      }
    
      void onTap(int value) {
        setState(() {
          this._currentIndex = value;
        });
      }
    
      @override
      void onEnergyReading() {
    
      }
    
      @override
      void onEquipmentRepair() {
    
      }
    
      @override
      void onScanCallBack() {
    
      }
    }
    

    2.dialog

    static show(BuildContext context,
          {MoreTabDialogCallBack callBack, AnimationController animationController}) {
        showModalBottomSheet(
          //设置背景色,背景为透明
          backgroundColor: ColorUtils.CLEAR,
          context: context,
          builder: (BuildContext context) {
            return SafeArea(
              child: AnimatedPadding(
                padding: MediaQuery.of(context).viewInsets,  //边距(必要)
                duration: const Duration(milliseconds: 100), //时常 (必要)
                child: Container(
                  //设置内容背景色,背景为透明
                  color: ColorUtils.CLEAR,
                  margin: new EdgeInsets.only(bottom: 13),
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: <Widget>[
                      ScaleTransition(
                        scale: animationController,
                        alignment: Alignment.bottomCenter,
                        child: Container(
                          width: 5000,
                          height: 150,
                          margin: new EdgeInsets.all(20),
                          decoration: BoxDecoration(
                            borderRadius: BorderRadius.all(
                              Radius.circular(10.0),
                            ),
                            color: Colors.white,
    //                    image: DecorationImage(
    //                      image: AssetImage("images/ic_work_bg.png"),
    //                      fit: BoxFit.fill,
    //                    ),
                          ),
                          child: Flex(
                            direction: Axis.horizontal,
                            children: <Widget>[
                              Expanded(
                                  flex: 1,
                                  child: GestureDetector(
                                    child: Column(
                                      mainAxisAlignment: MainAxisAlignment.center,
                                      children: <Widget>[
                                        Image.asset(
                                          "images/ic_more_dialog_scan.png",
                                          width: 60,
                                          height: 60,
                                        ),
                                        Container(
                                          margin: new EdgeInsets.only(top: 5),
                                          child: Text(
                                            "一",
                                            style: TextStyle(
                                                color: Colors.black, fontSize: 15),
                                          ),
                                        )
                                      ],
                                    ),
                                    onTap: () {
                                      callBack.onScanCallBack();
                                    },
                                  )),
                              Expanded(
                                  flex: 1,
                                  child: GestureDetector(
                                    child: Column(
                                      mainAxisAlignment: MainAxisAlignment.center,
                                      children: <Widget>[
                                        Image.asset(
                                          "images/ic_equipment_repair.png",
                                          width: 60,
                                          height: 60,
                                        ),
                                        Container(
                                          margin: new EdgeInsets.only(top: 5),
                                          child: Text(
                                            "一",
                                            style: TextStyle(
                                                color: Colors.black, fontSize: 15),
                                          ),
                                        )
                                      ],
                                    ),
                                    onTap: () {
                                      callBack.onEquipmentRepair();
                                    },
                                  )),
                              Expanded(
                                  flex: 1,
                                  child: GestureDetector(
                                    child: Column(
                                      mainAxisAlignment: MainAxisAlignment.center,
                                      children: <Widget>[
                                        Image.asset(
                                          "images/ic_energy_reading.png",
                                          width: 60,
                                          height: 60,
                                        ),
                                        Container(
                                          margin: new EdgeInsets.only(top: 5),
                                          child: Text(
                                            "一",
                                            style: TextStyle(
                                                color: Colors.black, fontSize: 15),
                                          ),
                                        )
                                      ],
                                    ),
                                    onTap: () {
                                      callBack.onEnergyReading();
                                    },
                                  )),
                            ],
                          ),
                        ),
                      ),
                      ScaleTransition(
                        scale: animationController,
                        alignment: Alignment.center,
                        child: GestureDetector(
                          onTap: () {
                            Navigator.of(context).pop();
                          },
                          child: Container(
                            width: 60,
                            height: 60,
                            decoration: BoxDecoration(
                              color: Colors.green,
                              shape: BoxShape.circle,
                            ),
                            child: Icon(Icons.close, color: Colors.white,),
                            padding: new EdgeInsets.all(3),
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
              ),
    
            );
          },
        );
      }
    

    相关文章

      网友评论

          本文标题:【Flutter】自己实现底部凸起导航栏

          本文链接:https://www.haomeiwen.com/subject/kttebctx.html