[Flutter-1] HelloVicent - tabBar 的实现

164 阅读2分钟

从实现TaBar开始;

1-1.jpg

  1. 导入对应的图标并在 pubspec.yaml 中对资源文件进行声明;
      # To add assets to your application, add an assets section, like this:
      assets:
         - assets/images/tabBar/ic_home_add.png
         - assets/images/tabBar/ic_home_discover_night_normal.png
         - assets/images/tabBar/ic_home_discover_normal.png
         - assets/images/tabBar/ic_home_discover_select.png
         - assets/images/tabBar/ic_home_synthesize_night_normal.png
         - assets/images/tabBar/ic_home_synthesize_normal.png
         - assets/images/tabBar/ic_home_synthesize_select.png
         - assets/images/tabBar/ic_home_tweet_night_normal.png
         - assets/images/tabBar/ic_home_tweet_normal.png
         - assets/images/tabBar/ic_home_tweet_select.png
         - assets/images/tabBar/ic_home_user_night_normal.png
         - assets/images/tabBar/ic_home_user_normal.png
         - assets/images/tabBar/ic_home_user_select.png
  1. 在pages文件夹下,创建5个对应的主页面;

  2. main.dart 进行tabBar的编写;

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:hello_oschina/common/ThemeUtils.dart';
import 'package:hello_oschina/pages/FindPage.dart';
import 'package:hello_oschina/pages/MyPage.dart';
import 'package:hello_oschina/pages/PostTopicPage.dart';
import 'package:hello_oschina/pages/SummaryPage.dart';
import 'package:hello_oschina/pages/TweetsPage.dart';

void main() {
  runApp(const MyClient());
}

class MyClient extends StatefulWidget {
  const MyClient({super.key});

  @override
  State<MyClient> createState() => _MyClientState();
}

class _MyClientState extends State<MyClient> {

  final Color selectedTabTextColor = const Color(0xff63ca6c);
  final Color normalTabTextColor = const Color(0xff969696);
  Color themeColor = ThemeUtils.defaultColor;

  //当前tab坐标
  int _tabIndex = 0;

  //tabBar 图标集合
  late List<List<Image>> tabImages;

  //app主体
  late IndexedStack _body;

  //设置tabBar上的所有页面
  final List<Widget> pages = [
    SummaryPage(),
    TweetsPage(),
    PostTopicPage(),
    FindPage(),
    MyPage()
  ];

  //获取tabIcon并设置尺寸大小
  Image getTabIcon(path) {
    return Image.asset(path, width: 24.0, height: 24.0);
  }

  //设置tab icon
  Image getNowTabIcon(int nowIndex) {
    return nowIndex == _tabIndex
        ? tabImages[nowIndex][1]
        : tabImages[nowIndex][0];
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();

    tabImages = [
      [
        getTabIcon('assets/images/tabBar/ic_home_synthesize_normal.png'),
        getTabIcon('assets/images/tabBar/ic_home_synthesize_select.png'),
        getTabIcon('assets/images/tabBar/ic_home_synthesize_night_normal.png')
      ],
      [
        getTabIcon('assets/images/tabBar/ic_home_tweet_normal.png'),
        getTabIcon('assets/images/tabBar/ic_home_tweet_select.png'),
        getTabIcon('assets/images/tabBar/ic_home_tweet_night_normal.png')
      ],
      [
        Image.asset('assets/images/tabBar/ic_home_add.png',
            width: 44.0, height: 44.0),
        Image.asset('assets/images/tabBar/ic_home_add.png',
            width: 44.0, height: 44.0),
      ],
      [
        getTabIcon('assets/images/tabBar/ic_home_discover_normal.png'),
        getTabIcon('assets/images/tabBar/ic_home_discover_select.png'),
        getTabIcon('assets/images/tabBar/ic_home_discover_night_normal.png')
      ],
      [
        getTabIcon('assets/images/tabBar/ic_home_user_normal.png'),
        getTabIcon('assets/images/tabBar/ic_home_user_select.png'),
        getTabIcon('assets/images/tabBar/ic_home_user_night_normal.png')
      ]
    ];
  }

  @override
  Widget build(BuildContext context) {
    _body = IndexedStack(
      index: _tabIndex,
      children: pages,
    );

    return MaterialApp(
      theme: ThemeData(primaryColor: themeColor),
      home: Scaffold(
        body: _body,
        bottomNavigationBar:
        //第二种,创建后中间的加号label不能省略
        //showSelectedLabels和showUnselectedLabels只能全局设置,不能控制单个的BottomNavigationBarItem
        //感觉如果需要实现,就只能去考虑自定义一个底部的TabBar了
        //The argument [icon] should not be null and the argument [label] should not be null when used in a Material Design's [BottomNavigationBar].
            BottomNavigationBar(
          items: <BottomNavigationBarItem>[
            BottomNavigationBarItem(icon: getNowTabIcon(0), label: '综合'),
            BottomNavigationBarItem(icon: getNowTabIcon(1), label: '动弹'),
            BottomNavigationBarItem(icon: getNowTabIcon(2), label: ""),
            BottomNavigationBarItem(icon: getNowTabIcon(3), label: '发现'),
            BottomNavigationBarItem(icon: getNowTabIcon(4), label: '我的'),
          ],
          type: BottomNavigationBarType.fixed,
          selectedItemColor: selectedTabTextColor,
          unselectedItemColor: normalTabTextColor,
          selectedLabelStyle: const TextStyle(
            fontWeight: FontWeight.bold,
          ),
          unselectedLabelStyle: const TextStyle(
            fontWeight: FontWeight.bold,
          ),
          currentIndex: _tabIndex,
          //showSelectedLabels: false,
          //showUnselectedLabels: false,
          backgroundColor: Colors.white,
          onTap: (index) {
            setState(() {
              _tabIndex = index;
            });
          },
        ),

        //第一种,创建无法改变tabBar的label字体
        // CupertinoTabBar(
        //   items: <BottomNavigationBarItem>[
        //     BottomNavigationBarItem(
        //         icon: getNowTabIcon(0),label: '综合'),
        //     BottomNavigationBarItem(
        //         icon: getNowTabIcon(1),label: '动弹'),
        //     BottomNavigationBarItem(
        //         icon: getNowTabIcon(2)),
        //     BottomNavigationBarItem(
        //         icon: getNowTabIcon(3),label: '发现'),
        //     BottomNavigationBarItem(
        //         icon: getNowTabIcon(4),label: '我的'),
        //   ],
        //   activeColor: selectedTabTextColor,
        //   inactiveColor: normalTabTextColor,
        //   currentIndex: _tabIndex,
        //   backgroundColor: Colors.white,
        //   onTap: (index){
        //     setState(() {
        //       _tabIndex = index;
        //     });
        //   },
        // ),

      ),
    );
  }
}

代码第一种 CupertinoTabBar 效果:

1-3.png

代码第二种 BottomNavigationBar效果:

1-2.png

  1. 设置tabBarItem的时候出现的问题,在网上查了很多,没有解决的办法,BottomNavigationBar部分的代码,去实现原App的tabBar效果;貌似只能去自定义才能实现;

  2. 现行先采用 CupertinoTabBar 的方式, 如有能实现的方法,烦请不吝赐教;

Flutter在新版对BottomNavigationBarItem进行了破坏性的改动,改动前的title属性,传一个 new Container()就可以实现,现在改为label属性只能传String类型了。 flutter.cn/docs/releas…