zoukankan      html  css  js  c++  java
  • Flutter 底部导航栏bottomNavigationBar

    实现一个底部导航栏,包含3到4个功能标签,点击对应的导航标签可以切换到对应的页面内容,并且页面抬头显示的内容也会跟着改变。
    实际上由于手机屏幕大小的限制,底部导航栏的功能标签一般在3到5个左右,如果太多,会比较拥挤,影响用户体验,实际上目前市面上大多数APP的底部导航标签都控制在4到5个左右。既美观、又不会让用户觉得功能繁杂。这个功能的实现需要用到flutter里的BottonNavigationBar这个控件。
    属性名 类型 说明
    currentIndex int 当前索引,用来切换按钮控制
    fixedColor Color 选中按钮的颜色,如果没有指定值,则用系统主题色
    iconSize double 按钮图标大小
    items List<BottomNavigationBarItem> 底部导航条按钮集。每一项是一个BottomNavigationBarItem,有icon图标及title属性
    onTap ValueChanged<int> 按下其中某一个按钮回调事件,需要根据返回的索引设置当前索引
    首先我们新建一个底部导航控件,由于点击导航标签的时候页面内容是会发生改变的,所以这是一个有状态的控件。
    import 'package:flutter/material.dart';
    import './home.dart';
    import './contacts.dart';
    import './me.dart';
    
    // 应用页面使用有状态Widget
    class App extends StatefulWidget {
      @override
      AppState createState() => AppState();
    }
    //应用页面状态实现类
    class AppState extends State<App> {
      //当前选中页面索引
      var _currentIndex = 0;
      //聊天页面
      HomePage home;
      //好友页面
      Contacts contacts;
      //我的页面
      Personal me;
    
      //根据当前索引返回不同的页面
      currentPage(){
        switch(_currentIndex) {
          case 0:
            //返回聊天页面
            if(home == null) {
              home = new HomePage();
            }
            return home;
          case 1:
            //返回好友页面
            if(contacts == null) {
              contacts = new Contacts();
            }
            return contacts;
          case 2:
            //返回我的页面
            if(me == null) {
              me = new Personal();
            }
            return me;
        }
      }
    
      @override
      Widget build(BuildContext context) {
    
        return Scaffold(
    
          //底部导航按钮
          bottomNavigationBar: new BottomNavigationBar(
            //通过fixedColor设置选中item的颜色
            fixedColor:Colors.red,
            type: BottomNavigationBarType.fixed,
            //当前页面索引
            currentIndex: _currentIndex,
            //按下后设置当前页面索引
            onTap: ((index){
              setState(() {
                _currentIndex = index;
              });
            }),
            //底部导航按钮项
            items: [
              //导航按钮项传入文本及图标
              new BottomNavigationBarItem(
                title: new Text(
                  '聊天',
                  style: TextStyle(
                    color: _currentIndex == 0 ? Color(0xFFF54343) : Color(0xff999999) //0x 后面开始 两位FF表示透明度16进制 后面是颜色
                  ),
                ),
                //判断当然索引做图片切换显示
                icon: _currentIndex == 0 
                  ? Image.asset(
                    'images/nav-icon-index.active.png',
                     32.0,
                    height: 32.0,
                  ) 
                  : Image.asset(
                    'images/nav-icon-index.png',
                     32.0,
                    height: 32.0,
                  )
              ),
              new BottomNavigationBarItem(
                title: new Text(
                  '好友',
                  style: TextStyle(
                    color: _currentIndex == 1 ? Color(0xFFF54343) : Color(0xff999999)
                  ),
                ),
                //判断当然索引做图片切换显示
                icon: _currentIndex == 1 
                  ? Image.asset(
                    'images/nav-icon-cat.active.png',
                     32.0,
                    height: 32.0,
                  ) 
                  : Image.asset(
                    'images/nav-icon-cat.png',
                     32.0,
                    height: 32.0,
                  )
              ),
              new BottomNavigationBarItem(
                title: new Text(
                  '我的',
                  style: TextStyle(
                    color: _currentIndex == 2 ? Color(0xFFF54343) : Color(0xff999999)
                  ),
                ),
                //判断当然索引做图片切换显示
                icon: _currentIndex == 2 
                  ? Image.asset(
                    'images/nav-icon-user.active.png',
                     32.0,
                    height: 32.0,
                  ) 
                  : Image.asset(
                    'images/nav-icon-user.png',
                     32.0,
                    height: 32.0,
                  )
              ),
            ],
          ),
    
          //中间显示当前页面
          body: currentPage(),
    
        );
      }
    }
    fixedColor设置选中的颜色,下面可以不单独写color。
     

    新建三个dart文件,分别用于新建3个主体展示页面,这三个页面都是带一个appbar和body,appbar用于显示对应的导航标签,body里显示标签大图标。三个文件的写法基本是一致的。

    import 'package:flutter/material.dart';
    
    class Personal extends StatefulWidget{
      @override
      State<StatefulWidget> createState() {
        return new PersonalState();
      }
    }
    
    class PersonalState extends State<Personal>{
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          appBar: new AppBar(
            title: new Text('我的'),
          ),
          body: new Center(
            child: Icon(Icons.mood,size: 130.0,color: Colors.blue,),
          ),
        );
      }
    }

     另外一种实现方法,重新initState()方法:

    List<Widget> blist = List();
     @override
     void initState(){
        blist
          ..add(HomePage())
          ..add(Contacts())
          ..add(Personal());
        super.initState();
      }

    这里的..add()是Dart语言的..语法,如果你学过编程模式,你一定听说过建造者模式,简单来说就是返回调用者本身。这里list后用了..add(),还会返回list,然后就一直使用..语法,能一直想list里增加widget元素。 最后我们调用了一些父类的initState()方法。

    完整代码:

    import 'package:flutter/material.dart';
    import './home.dart';
    import './contacts.dart';
    import './me.dart';
    
    class MyApp extends StatefulWidget {
      @override
      MyAppState createState() => MyAppState();
    }
    
    class MyAppState extends State<MyApp>  {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: Text('底部导航示例')),
          body: BottomNavigationWidget(),
        );
      }
    }
    
    class BottomNavigationWidget extends StatefulWidget {
    
      _BottomNavigationWidgetState createState() => _BottomNavigationWidgetState();
    }
    
    class _BottomNavigationWidgetState extends State<BottomNavigationWidget> {
      final _BottomNavigationColor = Colors.red;
      int _currentIndex = 0;
      List<Widget> blist = List();
    
      @override
      void initState(){
        blist
          ..add(HomePage()) //建造者模式,简单来说就是返回调用者本身。这里blist后用了..add(),还会返回blist
          ..add(Contacts())
          ..add(Personal());
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
           bottomNavigationBar:BottomNavigationBar(
             items: [
               BottomNavigationBarItem(
                icon: Icon(Icons.home,color: _BottomNavigationColor,),
                title:Text('Hmoe',style: TextStyle(color: _BottomNavigationColor),) 
               ),
               BottomNavigationBarItem(
                icon: Icon(Icons.email,color: _BottomNavigationColor,),
                title:Text('Email',style: TextStyle(color: _BottomNavigationColor),) 
               ),
               BottomNavigationBarItem(
                icon: Icon(Icons.pages,color: _BottomNavigationColor,),
                title:Text('Pages',style: TextStyle(color: _BottomNavigationColor),) 
               ),
             ],
             currentIndex: _currentIndex, //当前页面索引,高亮
             onTap: (int index){
               setState(() {
                 _currentIndex = index; 
               });
             },
           ) ,
           body: blist[_currentIndex],
        );
      }
    }
  • 相关阅读:
    linux 如何使用密钥登录 (CentOs)
    linux修改ssh端口 以及禁止root远程登录 (实验机 CentOs)
    查看Windows端口及端口关闭方法
    使用 Linux 终端 SSH 登录 VPS
    修改Chrome默认搜索引擎为Google.com
    Windows 小技巧: 變更輸入法順序
    CentOS 安装BitTorrent Sync详细步骤
    Android手机部分名词浅谈
    PPTP模式跟L2TP模式有什么不同
    .CO域名快被这帮搞IT的玩坏了……
  • 原文地址:https://www.cnblogs.com/joe235/p/11176711.html
Copyright © 2011-2022 走看看