Flutter创建TabBar

news2024/11/25 9:47:13

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1267815.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

由于找不到steam_api64.dll如何修复?steam_api64.dll丢失多种解决方法

steam_api64.dll文件介绍 steam_api64.dll是Steam平台的一个关键组件&#xff0c;主要用于支持Steam客户端和相关游戏的应用程序。这个文件缺失或损坏会导致Steam及相关游戏无法正常运行。它位于Steam安装目录的bin子文件夹中。 steam_api64.dll丢失的原因 系统误删&#xf…

品味丰富美食,羊大师温暖心灵

品味丰富美食&#xff0c;羊大师温暖心灵 冬季来临&#xff0c;寒冷的天气让人们渴望寻找一种温暖和满足感&#xff0c;这时候美食便成了一种心灵享受。冬季与美食的结合&#xff0c;使得人们在寒冷的冬日也能感受到温暖与欢乐。本文小编羊大师将带大家领略冬季与美食的完美结…

C库函数—sprintf

函数介绍&#xff1a; C 库函数 int sprintf(char *str, const char *format, ...) 发送格式化输出到 str 所指向的字符串。 参数&#xff1a; str -- 这是指向一个字符数组的指针&#xff0c;该数组存储了 C 字符串。format -- 这是字符串&#xff0c;包含了要被写入到字符串 …

网络入门---网络的大致了解

目录标题 网络发展的简单认识协议作用的理解协议的本质什么是协议分层网络通信所面对的问题OSI七层模型TCP/IP模型协议报头的理解局域网通信局域网通信基本原理报头的问题局域网的特点跨网的网络链接如何查看mac地址 网络发展的简单认识 通过之前的学习我们知道计算机是给人提…

九章正式推出『智能驾驶产业数据库』

为了更好地研究产业变化趋势&#xff0c;在定性分析之外增加更多定量分析的内容&#xff0c;从而帮助自动驾驶产业内的朋友们更快速、更精准地把握市场变化&#xff0c;2022年底&#xff0c;九章决定要做智能驾驶产业数据库。 历时将近一年后&#xff0c;从敲定数据库负责人&am…

【古月居《ros入门21讲》学习笔记】10_话题消息的定义与使用

目录 说明&#xff1a; 1. 话题模型 2. 实现过程&#xff08;C&#xff09; 自定义话题消息 Person.msg文件内容 Person.msg文件内容说明 编译配置 在package.xml文件中添加功能包依赖 在CMakeLists.txt中添加编译选项 编译生成语言相关文件 创建发布者代码&#xff…

【Android Jetpack】Hilt 依赖注入框架

文章目录 依赖注入DaggerHiltKoin添加依赖项Hilt常用注解的含义HiltAndroidAppAndroidEntryPointInjectModuleInstallInProvidesEntryPoint Hilt组件生命周期和作用域如何使用 Hilt 进行依赖注入 依赖注入 依赖注入是一种软件设计模式&#xff0c;它允许客户端从外部源获取其依…

高级IO—poll,epoll,reactor

高级IO—poll,epoll,reactor 文章目录 高级IO—poll,epoll,reactorpoll函数poll函数接口poll服务器 epollepoll的系统调用epoll_createepoll_ctlepoll_wait epoll的工作原理epoll的工作方式水平触发边缘触发 epoll服务器 reactor poll函数 poll函数是一个用于多路复用的系统调…

docker-compose Foxmic dt版

Foxmic dt 版前言 实现企业对资产的基本管理,包含对资产的登记、维修、调拨、转移等基本功能的支持,并提供对资产的耗材、库存进行管理,有完善的组织架构,非常适合中小企业的需求系统整体覆盖了基本的资产管理、合同管理、运维服务、运维服务、数据中心设备管理等多个模块。…

白盒测试 接口测试 自动化测试

一、什么是白盒测试 白盒测试是一种测试策略&#xff0c;这种策略允许我们检查程序的内部结构&#xff0c;对程序的逻辑结构进行检查&#xff0c;从中获取测试数据。白盒测试的对象基本是源程序&#xff0c;所以它又称为结构测试或逻辑驱动测试&#xff0c;白盒测试方法一般分为…

JVM执行引擎以及调优

1.JVM内部的优化逻辑 1.1JVM的执行引擎 javac编译器将Person.java源码文件编译成class文件[我们把这里的编译称为前期编译]&#xff0c;交给JVM运行&#xff0c;因为JVM只能认识class字节码文件。同时在不同的操作系统上安装对应版本的JDK&#xff0c;里面包含了各自屏蔽操作…

Linux下Docker 离线安装详细步骤,亲测成功

1.离线原因&#xff1a;公司新创不能使用开元linux&#xff0c;使用了一个变种centOS&#xff0c;致使yum被禁 2.步骤&#xff1a; 2.1 下载docker tar包&#xff0c;下载地址&#xff1a;Index of linux/https://download.docker.com/linux/ 2.2 新建自己的软件目录&am…

数字化转型的核心是数据,还是应用?_光点科技

数字化转型是当今世界各行各业的热门话题。它不仅仅是将传统的业务流程、产品和服务数字化&#xff0c;更是一种全面的业务战略转变。在这个转变过程中&#xff0c;数据和应用都扮演着至关重要的角色。但究竟哪一个是数字化转型的核心&#xff1f;这个问题值得深入探讨。 我们来…

【JavaEE初阶】死锁问题

目录 一、死锁的三种典型场景 1、一个线程&#xff0c;一把锁 2、两个线程&#xff0c;两把锁 3、N个线程&#xff0c;M把锁 死锁&#xff0c;是多线程代码中的一类经典问题。我们知道加锁是能解决线程安全问题的&#xff0c;但是如果加锁的方式不当&#xff0c;就可能产生死…

力扣:185. 部门工资前三高的所有员工(Python3)

题目&#xff1a; 表: Employee ----------------------- | Column Name | Type | ----------------------- | id | int | | name | varchar | | salary | int | | departmentId | int | ----------------------- id 是该表的主键列(具…

Condition 源码解析

Condition 源码解析 文章目录 Condition 源码解析一、Condition二、Condition 源码解读2.1. lock.newCondition() 获取 Condition 对象2.2. condition.await() 阻塞过程2.3. condition.signal() 唤醒过程2.4. condition.await() 被唤醒后 三、总结 一、Condition 在并发情况下…

linux 之iptables

1.iptables防火墙基本介绍 Linux系统的防火墙&#xff1a;IP信息包过滤系统&#xff0c;它实际上由两个组件 netfilter和 iptables 组成。 主要工作在网络层&#xff0c;针对IP数据包。体现在对包内的IP地址、端口、协议等信息的处理上。 iptables由软件包iptables提供的命令…

诊所电子处方范例之配方模板如何添加到处方中操作教程

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 诊所门诊在开电子处方的时候&#xff0c;如果能使用模板一键导入&#xff0c;则可以节…

8个程序员常用的开发工具,各位老铁请收好!

Chat GPT的升级节奏让人们越来越惊讶的同时&#xff0c;也让大家感觉到了压力&#xff0c;在如此快节奏的互联网世界中&#xff0c;开发人员需要不断学习与更新知识&#xff0c;保持领先地位并高效地交付高质量软件。 无论是集成开发环境 (IDE)、版本控制系统、测试工具、协作…

二阶常系数非齐次线性微分方程:类型二

或 (1) (2) 欧拉公式 (3) 设(3)有特解 是(1)的特解 是&#xff08;2&#xff09;的特解 例 &#xff1a; 解 所以其通解为 这是属于上一篇提到的第一种情况 其特解 即 简化 -2a1 a-1/2 原方程特解为 原方程通解为 解法二 将 或 改写为 设是特征方程的k重根&a…