Flutter创建TabBar

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

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

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

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使用自定义图标,但不使用图标所带的颜色。

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使用系统图标

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,隐藏下划线
          ),
        ),
      ),
    );
  }
}

相关推荐

  1. Flutter创建自定义的左对齐TabBar组件

    2023-12-06 23:42:01       20 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-06 23:42:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-06 23:42:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-06 23:42:01       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-06 23:42:01       20 阅读

热门阅读

  1. MVCC-

    2023-12-06 23:42:01       29 阅读
  2. 03.PostgreSQL常用索引与优化

    2023-12-06 23:42:01       29 阅读
  3. vue3.0 写法 格式

    2023-12-06 23:42:01       27 阅读
  4. TCP与UDP的区别

    2023-12-06 23:42:01       45 阅读
  5. 基于Boost::Beast模块的小型HTTP服务器编程

    2023-12-06 23:42:01       34 阅读
  6. Spark_spark参数配置优先级

    2023-12-06 23:42:01       39 阅读
  7. spark写入数据报错

    2023-12-06 23:42:01       36 阅读
  8. pymysql的基本用法

    2023-12-06 23:42:01       41 阅读
  9. 网络数据通信—ProtoBuf实现序列化和反序列化

    2023-12-06 23:42:01       39 阅读
  10. git小白初学习

    2023-12-06 23:42:01       29 阅读
  11. 让 OpenAI GPT4 出 10 道题测试其他开源大语言模型

    2023-12-06 23:42:01       24 阅读
  12. 什么是DDI?DDI的原理和作用是什么?一文看懂

    2023-12-06 23:42:01       36 阅读
  13. USTC Fall2023 高级人工智能期末考试回忆版

    2023-12-06 23:42:01       39 阅读
  14. 力扣labuladong一刷day29天二叉树

    2023-12-06 23:42:01       40 阅读