Flutter创建TabBar

使用TabBar和TabBarView来创建一个包含"首页"、"分类"和"我的"的TabBar。每个Tab对应一个Tab控件,TabBarView中的每个页面对应一个Widget。

1.Tab使用自定义图标和颜色

一般UI设计的图会带渐变色之类的,应该保持图片的原状,不能随便就给改成纯色。

Dart 复制代码
import 'package:flutter/material.dart'; // 导入Flutter Material组件库

void main() {
  WidgetsFlutterBinding.ensureInitialized(); // 确保Flutter绑定到框架初始化
  runApp(const MyApp()); // 运行应用
}

class MyApp extends StatelessWidget {
  // 创建一个无状态的组件MyApp
  const MyApp({super.key}); // 构造函数,接收一个Key

  @override
  Widget build(BuildContext context) {
    // 重写build方法,构建UI
    return MaterialApp(
      debugShowCheckedModeBanner: false, // 禁用右上角的Debug标志
      theme: ThemeData(
        // 设置应用主题
        tabBarTheme: TabBarTheme(
          // 设置TabBar主题
          overlayColor: MaterialStateProperty.all<Color>(
              Colors.transparent), // 设置点击时的背景颜色为透明
        ),
      ),
      home: DefaultTabController(
        // 使用DefaultTabController来协调选项卡选择和内容显示
        initialIndex: 0, // 设置初始选中的Tab索引为0(首页)
        length: 3, // 设置Tab的数量
        child: Scaffold(
          // 创建一个Scaffold,提供基本的Material Design布局结构
          appBar: AppBar(
            // 创建一个AppBar
            title: const Text('My Flutter App'), // 设置AppBar的标题
          ), // 去掉顶部的导航栏,只需将appBar设置为null
          body: const TabBarView(
            // 创建TabBarView,用于显示Tab的内容
            physics:
                NeverScrollableScrollPhysics(), // 禁止在 TabBarView 中滑动切换选项卡,添加这行代码
            children: [
              Center(child: Text('首页:这里可以展示应用的主要内容')), // Tab 1 内容
              Center(child: Text('分类:这里可以展示商品或信息的分类')), // Tab 2 内容
              Center(child: Text('我的:这里可以展示用户的个人信息和设置')), // Tab 3 内容
            ],
          ),
          bottomNavigationBar: const TabBar(
            // 创建底部导航TabBar
            tabs: [
              // Tab项定义
              Tab(
                  icon: _TabIcon(
                      // 自定义Tab图标
                      activeIcon: // 选中状态的图标
                          AssetImage("assets/images/tab_home_selected.png"),
                      inactiveIcon: // 未选中状态的图标
                          AssetImage("assets/images/tab_home_default.png"),
                      index: 0), // Tab索引
                  text: "首页"), // Tab文本
              Tab(
                  icon: _TabIcon(
                      activeIcon:
                          AssetImage("assets/images/tab_category_selected.png"),
                      inactiveIcon:
                          AssetImage("assets/images/tab_category_default.png"),
                      index: 1),
                  text: "分类"),
              Tab(
                  icon: _TabIcon(
                      activeIcon:
                          AssetImage("assets/images/tab_mine_selected.png"),
                      inactiveIcon:
                          AssetImage("assets/images/tab_mine_default.png"),
                      index: 2),
                  text: "我的"),
            ],
            isScrollable: false, // 禁用滚动功能
            labelStyle: TextStyle(fontWeight: FontWeight.bold), // 设置文本样式为加粗
            labelColor: Colors.red, // 选项选中的颜色
            unselectedLabelColor: Colors.black, // 选项未选中的颜色
            indicatorColor: Colors.blue, // 下滑线颜色
            indicator: BoxDecoration(), // 设置为空的Container,隐藏下划线
          ),
        ),
      ),
    );
  }
}

class _TabIcon extends StatelessWidget {
  // 创建一个无状态的组件_TabIcon,用于显示Tab图标
  final AssetImage activeIcon; // 选中状态的图标
  final AssetImage inactiveIcon; // 未选中状态的图标
  final int index; // Tab索引

  const _TabIcon({
    // 构造函数
    Key? key,
    required this.activeIcon,
    required this.inactiveIcon,
    required this.index,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    // 重写build方法,构建UI
    final controller =
        DefaultTabController.of(context); // 获取当前上下文的DefaultTabController
    return ValueListenableBuilder(
      // 创建ValueListenableBuilder来监听变化
      valueListenable: controller.animation!, // 监听TabController的动画
      builder: (BuildContext context, value, Widget? child) {
        // 构建器回调
        final tabIndex = controller.index; // 获取当前选中的Tab索引
        return Image(
          // 创建Image组件来显示图标
          image:
              tabIndex == index ? activeIcon : inactiveIcon, // 根据Tab索引显示对应的图标
          width: 24, // 图标宽度
          height: 24, // 图标高度
        );
      },
    );
  }
}

这段代码创建了一个简单的Flutter应用,其中包含一个具有三个Tab的底部导航栏。每个Tab都有自己的图标和文本。这些Tab可以在用户点击它们时切换显示内容。代码中还包含了对Tab图标颜色的自定义处理,确保图标显示其原始颜色。

示意图:

2.Tab使用自定义图标,但不使用图标所带的颜色。

Dart 复制代码
import 'package:flutter/material.dart';

void main() {
  // 确保Flutter绑定到框架初始化
  WidgetsFlutterBinding.ensureInitialized();
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false, // 禁用右上角的Debug标志
      theme: ThemeData(
        tabBarTheme: TabBarTheme(
          overlayColor: MaterialStateProperty.all<Color>(
              Colors.transparent), // 设置点击时的背景颜色为透明
        ),
      ),
      home: DefaultTabController(
        length: 3,
        child: Scaffold(
          appBar: AppBar(
            title: const Text('My Flutter App'),
          ), // 去掉顶部的导航栏,只需将appBar设置为null
          body: const TabBarView(
            children: [
              Center(child: Text('首页:这里可以展示应用的主要内容')),
              Center(child: Text('分类:这里可以展示商品或信息的分类')),
              Center(child: Text('我的:这里可以展示用户的个人信息和设置')),
            ],
          ),
          bottomNavigationBar: const TabBar(
            tabs: [
              Tab(
                  icon: _TabIcon(
                      activeIcon:
                          AssetImage("assets/images/tab_home_selected.png"),
                      inactiveIcon:
                          AssetImage("assets/images/tab_home_default.png"),
                      index: 0),
                  text: "首页"),
              Tab(
                  icon: _TabIcon(
                      activeIcon:
                          AssetImage("assets/images/tab_category_selected.png"),
                      inactiveIcon:
                          AssetImage("assets/images/tab_category_default.png"),
                      index: 1),
                  text: "分类"),
              Tab(
                  icon: _TabIcon(
                      activeIcon:
                          AssetImage("assets/images/tab_mine_selected.png"),
                      inactiveIcon:
                          AssetImage("assets/images/tab_mine_default.png"),
                      index: 2),
                  text: "我的"),
            ],
            labelColor: Colors.red, // 选项选中的颜色
            unselectedLabelColor: Colors.grey, // 选项未选中的颜色

            indicatorColor: Colors.blue, // 下滑线颜色
            indicator: BoxDecoration(), // 设置为空的Container,隐藏下划线
          ),
        ),
      ),
    );
  }
}

class _TabIcon extends StatelessWidget {
  final AssetImage activeIcon;
  final AssetImage inactiveIcon;
  final int index;

  const _TabIcon({
    Key? key,
    required this.activeIcon,
    required this.inactiveIcon,
    required this.index,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final tabIndex = DefaultTabController.of(context).index;
    return ImageIcon(
      tabIndex == index ? activeIcon : inactiveIcon,
    );
  }
}

3.Tab使用系统图标

Dart 复制代码
import 'package:flutter/material.dart';

void main() {
  // 确保Flutter绑定到框架初始化
  WidgetsFlutterBinding.ensureInitialized();
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false, // 禁用右上角的Debug标志
      theme: ThemeData(
        tabBarTheme: TabBarTheme(
          overlayColor: MaterialStateProperty.all<Color>(
              Colors.transparent), // 设置点击时的背景颜色为透明
        ),
      ),
      home: DefaultTabController(
        length: 3,
        child: Scaffold(
          appBar: AppBar(
            title: const Text('My Flutter App'),
          ), // 去掉顶部的导航栏,只需将appBar设置为null
          body: const TabBarView(
            children: [
              Center(child: Text('首页:这里可以展示应用的主要内容')),
              Center(child: Text('分类:这里可以展示商品或信息的分类')),
              Center(child: Text('我的:这里可以展示用户的个人信息和设置')),
            ],
          ),
          bottomNavigationBar: const TabBar(
            tabs: [
              Tab(icon: Icon(Icons.home), text: "首页"),
              Tab(icon: Icon(Icons.category), text: "分类"),
              Tab(icon: Icon(Icons.person), text: "我的"),
            ],
            labelColor: Colors.red, // 选项选中的颜色
            unselectedLabelColor: Colors.grey, // 选项未选中的颜色

            indicatorColor: Colors.blue, // 下滑线颜色
            indicator: BoxDecoration(), // 设置为空的Container,隐藏下划线
          ),
        ),
      ),
    );
  }
}
相关推荐
星秋Eliot11 小时前
Flutter多线程
flutter·async/await·isolate·flutter 多线程
农夫三拳_有点甜14 小时前
Flutter Assets & Media
flutter
林间风雨1 天前
flutter项目 -- 换logo、名称 、签名、打包
flutter
SoaringHeart1 天前
Flutter组件封装:页面点击事件拦截
前端·flutter
tangweiguo030519872 天前
Flutter与原生混合开发:实现完美的暗夜模式同步方案
android·flutter
程序员老刘2 天前
CTO紧急叫停AI编程!不是技术倒退,而是...
flutter·ai编程
leazer2 天前
Flutter TabBar 字体缩放动画抖动问题及优化方案
flutter
yuanpan2 天前
认识跨平台UI框架Flutter和MAUI区别,如何选。
flutter·ui·maui
无知的前端2 天前
一文精通-Flutter 状态管理
flutter
阿笑带你学前端2 天前
Drift数据库开发实战:类型安全的SQLite解决方案
前端·flutter