Flutter伪微信-002-使用BottomNavigationBar构建导航栏

154 阅读2分钟

前言

登录微信后映入眼帘的是微信四大功能键(微信、通讯录、发现、我的),这些功能按键提供了基础的页面导航功能。

想法

  • 使用Flutter的Scaffold脚手架组件的bottomNavigationBar来完成导航栏。
  • 先使用Flutter提供的系统Icon图标库

效果图

image.png

image.png

BottomNavigationBar简介

BottomNavigationBar的构造函数如下:

BottomNavigationBar({
    Key? key,
    required this.items,
    this.onTap,
    this.currentIndex = 0,
    this.elevation,
    this.type,
    Color? fixedColor,
    this.backgroundColor,
    this.iconSize = 24.0,
    Color? selectedItemColor,
    this.unselectedItemColor,
    this.selectedIconTheme,
    this.unselectedIconTheme,
    this.selectedFontSize = 14.0,
    this.unselectedFontSize = 12.0,
    this.selectedLabelStyle,
    this.unselectedLabelStyle,
    this.showSelectedLabels,
    this.showUnselectedLabels,
    this.mouseCursor,
  })

其中常用的属性为:

  • items:及对应的页面组件数组
  • currentIndex:默认显示第几个页面
  • type:组件类型,使用BottomNavigationBarType枚举,有fixedshifting两种。
    • fixed 是图标固定位置.
    • shifting的图标点击后会有一个漂移效果,
  • onTap:点击后的事件,一般用这个更新状态数据,以便更新页面。

其他属性用于控制样式的,可以根据实际需要设置图标大小,主题色,字体等参数。

构建导航栏

import 'package:flutter/material.dart';
import 'package:pseudo_we_chat/pages/directory/directory.dart';
import 'package:pseudo_we_chat/pages/discover/discover.dart';
import 'package:pseudo_we_chat/pages/home/home.dart';
import 'package:pseudo_we_chat/pages/message/message.dart';

class IndexPage extends StatefulWidget {
  // 定义初始化导航栏选择的下标,默认为0
  final int index;

  const IndexPage({Key? key, this.index = 0}) : super(key: key);

  @override
  State<IndexPage> createState() => _IndexPageState();
}

class _IndexPageState extends State<IndexPage> {
  late int _index;

  // 重写初始化状态方法进行下标赋值
  @override
  void initState() {
    super.initState();
    _index = widget.index;
  }

  // 定义导航栏组件集合
  final List<Widget> _pageItem = const [
    MessagePage(),
    DirectoryPage(),
    DiscoverPage(),
    HomePage(),
  ];

  // 定义图标Map(方便后期使用自定义图标库)
  final Map<String, Icon> _iconMap = const {
    "message": Icon(Icons.message),
    "directory": Icon(Icons.list),
    "discover": Icon(Icons.find_in_page),
    "home": Icon(Icons.person),
  };

  // 定义导航栏组件的数据
  final List<NavBarItem> _navBarItem = const [
    NavBarItem(icon: "message", label: "微信"),
    NavBarItem(icon: "directory", label: "通讯录"),
    NavBarItem(icon: "discover", label: "发现"),
    NavBarItem(icon: "home", label: "我的"),
  ];

  // 导航栏按钮按下事件
  void _onBottomNavigationBarTapped(index) {
    // 下标重新赋值,进行切换
    setState(() {
      _index = index;
    });
  }

  // 自定义构建导航栏组件的方法
  List<BottomNavigationBarItem> _getNavBarItem() {
    return _navBarItem
        .map((e) => BottomNavigationBarItem(
        icon: _iconMap[e.icon] ?? const Icon(Icons.search), label: e.label))
        .toList();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: IndexedStack(
          index: _index,
          children: _pageItem,
        ),
        bottomNavigationBar: BottomNavigationBar(
          type: BottomNavigationBarType.fixed, //设置类型
          currentIndex: _index,  //设置选中下标
          onTap: _onBottomNavigationBarTapped, //设置按钮按下事件
          items: _getNavBarItem(), //调用构建导航栏组件方法
        ));
  }
}

/// 自定义导航栏组件数据结构
class NavBarItem {
  const NavBarItem({required this.icon, required this.label});

  /// 图标
  final String icon;

  /// 名称
  final String label;
}

项目链接

github.com/BadKid90s/p…

大佬链接

developer.aliyun.com/profile/4w5…