flutter TabBar自定义指示器(带文字的指示器、上弦弧形指示器、条形背景指示器、渐变色的指示器)
带文字的TabBar指示器


1.绘制自定义TabBar的绿色带白色文字的指示器
2.将底部灰色文字与TabrBar层叠,并调整高度位置与胶囊指示器重叠
自定义的带文字的TabBar指示器
import 'package:atui/jade/utils/JadeColors.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';class MyCustomTextIndicator extends Decoration {final String text;const MyCustomTextIndicator({ this.text});BoxPainter createBoxPainter([VoidCallback onChanged]) {return _CustomTabIndicatorPainter(text: text);}
}class _CustomTabIndicatorPainter extends BoxPainter {final String text;_CustomTabIndicatorPainter({ this.text});void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {final rect = Rect.fromLTWH(offset.dx - 40.w,configuration.size.height - 60.w,configuration.size.width + 80.w,25,);final _gradientColors = [JadeColors.green_16, JadeColors.green_12];final paint = Paint()..shader = LinearGradient(colors: _gradientColors).createShader(rect);canvas.drawRRect(RRect.fromRectAndRadius(rect, Radius.circular(15)), paint);final _textPainter = TextPainter(text: TextSpan(text: text, style: TextStyle(color: Colors.white,fontSize: 22.sp,fontWeight: FontWeight.bold)),textDirection: TextDirection.ltr,);_textPainter.layout();_textPainter.paint(canvas, Offset(rect.left + (rect.width - _textPainter.width) / 2, rect.top + (rect.height - _textPainter.height) / 2));canvas.save();canvas.restore();}
}
引用:
//tabBar标签tab数据
List<Map<String, dynamic>> _tabs = [{'title': '严选', 'subTitle': '品质优选','range': 41},{'title': '优惠', 'subTitle': '阿推优惠','range': 42},{'title': '进口', 'subTitle': '阿推国际','range': 43},{'title': '推享金', 'subTitle': '排行榜','range': 45},];_tabBar(){return Stack(alignment: Alignment.bottomCenter,children: [Padding(padding: EdgeInsets.only(bottom: 20.w),child: Wrap(alignment: WrapAlignment.start,spacing: 40.w,runSpacing: 0,children: List.generate(_tabs.length, (index) {return Container(alignment: Alignment.center,width: 124.w,child: Text('${_tabs[index]['subTitle']}',style: TextStyle(color: JadeColors.grey,fontSize: 22.sp,fontWeight: FontWeight.bold),),);}),)),Container(padding: EdgeInsets.symmetric(horizontal: 40.w),child: TabBar(controller: _tabController,isScrollable: false,labelPadding: EdgeInsets.only(left: 10,right: 10,bottom: 10.w),indicator: MyCustomTextIndicator(text: _tabs[_currentIndex]['subTitle']),indicatorWeight: 60.w,labelColor: JadeColors.black,labelStyle: TextStyle(fontSize: 34.sp,fontWeight: FontWeight.bold,),unselectedLabelColor: JadeColors.black,unselectedLabelStyle: TextStyle(fontSize: 34.sp,fontWeight: FontWeight.bold,),indicatorSize: TabBarIndicatorSize.label,tabs: _tabs.map((e) => Text(e['title'])).toList(),onTap: (index) {setState(() {_currentIndex = index;});print('_currentIndex= $_currentIndex');},)),],);}_tabBarView(){return TabBarView(controller: _tabController,physics: const AlwaysScrollableScrollPhysics(),children: _tabs.map((e) {return MarketGoodsListPage(range: e['range']);}).toList());}
上弦的弧形TabBar指示器

自定义指示器
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';/*
* 自定义的上弦圆弧TabBar指示器
* */
class MyCustomArcIndicator extends Decoration {BoxPainter createBoxPainter([VoidCallback onChanged]) {return _CustomBoxPainter(this, onChanged);}
}class _CustomBoxPainter extends BoxPainter {final MyCustomArcIndicator decoration;_CustomBoxPainter(this.decoration, VoidCallback onChanged): super(onChanged);void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {final size = configuration.size;final newOffset = Offset(offset.dx + size.width / 2 - 10.w, size.height / 4);var paint = Paint();double rowHeight = 12;paint.strokeWidth = rowHeight / 4;paint.style = PaintingStyle.stroke;Path path = Path();Rect rect = Rect.fromLTWH(newOffset.dx, newOffset.dy + rowHeight / 2, rowHeight, rowHeight);path.arcTo(rect, pi / 4,pi / 2, true);paint.color = Color(0xFF56CEBA);paint.strokeCap = StrokeCap.round;paint.style = PaintingStyle.stroke;canvas.drawPath(path, paint);}
}
引用:
_tabBar(){return TabBar(isScrollable: true,labelPadding: EdgeInsets.only(left: 10,right: 10,bottom: 10.w),indicator: MyCustomArcIndicator(),labelColor: JadeColors.black,labelStyle: TextStyle(fontSize: 36.sp,fontWeight: FontWeight.w600,),unselectedLabelColor: Color(0xff333333),unselectedLabelStyle: TextStyle(fontSize: 36.sp,),indicatorSize: TabBarIndicatorSize.label,controller: providerOf<MainModel>().tabController,tabs: MainModel.catList().map((e) => Text(e['name'])).toList(),onTap: (index) {providerOf<MainModel>().currentTabIndex = index;if(index == 7){Provider.of<RewardPoolModel>(context, listen: false).searchMoneyData();}},);}
普通的TabBar自定义指示器
图1:

图2:

自定义指示器
import 'package:flutter/material.dart';class MyCustomIndicator extends Decoration {final double indWidth;final double indHeight;final double radius;final List<Color> indicatorColor;const MyCustomIndicator({this.indWidth = 70.0, this.indHeight = 12.0, this.radius = 5, this.indicatorColor});BoxPainter createBoxPainter([VoidCallback onChanged]) {return _CustomBoxPainter(this, onChanged, indWidth, indHeight, radius, indicatorColor);}
}class _CustomBoxPainter extends BoxPainter {final MyCustomIndicator decoration;final double indWidth;final double indHeight;final double radius;final List<Color> indicatorColor;_CustomBoxPainter(this.decoration, VoidCallback onChanged, this.indWidth, this.indHeight, this.radius,this.indicatorColor): super(onChanged);void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {final size = configuration.size;final newOffset = Offset(offset.dx + (size.width - indWidth) / 2, size.height - indHeight);final Rect rect = newOffset & Size(indWidth, indHeight);final Paint paint = Paint();if(indicatorColor == null || indicatorColor.isEmpty){paint.color = Colors.yellow;}else{if(indicatorColor.length == 1){paint.color = indicatorColor[0];}else if(indicatorColor.length > 1){paint.shader =LinearGradient(colors: indicatorColor, begin: Alignment.centerLeft, end: Alignment.centerRight).createShader(rect);}}paint.style = PaintingStyle.fill;canvas.drawRRect(RRect.fromRectAndRadius(rect, Radius.circular(radius)), // 圆角半径paint,);canvas.save();canvas.restore();}
}
图1效果的引用:
_tabBarView(){return Container(color: Colors.white,child: TabBar(isScrollable: false,labelPadding: EdgeInsets.symmetric(horizontal: 0),indicator: MyCustomIndicator(indicatorColor: [Colors.yellow]),labelColor: Color(0xff333333),labelStyle: TextStyle(fontSize: 30.sp,fontWeight: FontWeight.w600,),unselectedLabelColor: JadeColors.grey,unselectedLabelStyle: TextStyle(fontSize: 30.sp,fontWeight: FontWeight.w300),indicatorSize: TabBarIndicatorSize.label,controller: _tabController,tabs: _tabs.map((value) => Container(padding: EdgeInsets.symmetric(horizontal: 20.w),child: Text(value))).toList(),onTap: (index) {},),);}
图2效果的引用:
TabBar(tabs: tabs,isScrollable: false,unselectedLabelColor: const Color(0xFF000000),labelStyle: TextStyle(fontWeight: FontWeight.bold),labelColor: const Color(0xFF000000),indicatorSize: TabBarIndicatorSize.label,indicator: MyCustomIndicator(indicatorColor: [JadeColors.red,JadeColors.yellow],indHeight: 8.w,indWidth: 92.w),controller: _tabController,)
相关文章:
flutter TabBar自定义指示器(带文字的指示器、上弦弧形指示器、条形背景指示器、渐变色的指示器)
带文字的TabBar指示器 1.绘制自定义TabBar的绿色带白色文字的指示器 2.将底部灰色文字与TabrBar层叠,并调整高度位置与胶囊指示器重叠 自定义的带文字的TabBar指示器 import package:atui/jade/utils/JadeColors.dart; import package:flutter/material.dart; im…...
【Fargo】9:模拟图片采集的内存泄漏std::bad_alloc
std::bad_alloc 崩溃。这样的内存分配会导致内存耗尽 is simulating an image of size 640x480 with 3 bytes per pixel, resulting in an allocation of approximately 921,600 bytes (or around 900 KB) for each image. The error you’re encountering (std::bad_alloc) ty…...
c# 前端无插件打印导出实现方式
打印 打印导出分布页 model List<界面的数据模型类> using WingSoft; using Newtonsoft.Json; <style type"text/css">.modal-content {width: 800px;}.modal-body {height: 400px;} </style> <script type"text/javascript">$(…...
数组的初始化,参数传递,和求和
在自己做的这个C语言解释器中,数组的使用非常简便。下面小程序是一个例子。演示了数组的初始化,参数传递, 和求和。 all[] { WA12,OR8,CA54, ID4, MT4, WY3, NV6, UT6, AZ11, CO10, NM5, ND3,SD3,NE4, KS6, OK7,TX40, MN10, WI10,IA6, MO10,…...
初始JavaEE篇——多线程(1):Thread类的介绍与使用
找往期文章包括但不限于本期文章中不懂的知识点: 个人主页:我要学编程(ಥ_ಥ)-CSDN博客 所属专栏:JavaEE 目录 创建线程 1、继承 Thread类 2、实现Runnable接口 3、使用匿名内部类 1)继承Thread类的匿名内部类 2)…...
基于单片机的LED照明自动控制系统的设计
本设计主控核心芯片选用了AT89C51单片机,接入了光照采集模块、红外感应模块、继电器控制模块,通过控制发光二极管模拟教室智能灯组的控制。首先通过光敏感应的方式感应当前光照环境为白天还是夜晚,同时,红外感应模块感应是否有人。…...
C语言——头文件的使用
目录 前言头文件怎么包含 前言 这个专栏会专门讲一些C语言的知识,后续会慢慢更新,欢迎关注 C语言专栏 头文件怎么包含 在使用头文件的过程中,我们经常会遇到重定义、重复包含等问题,那么怎么编写头文件和使用头文件才能解决这些…...
LeetCode 精选 75 回顾
目录 一、数组 / 字符串 1.交替合并字符串 (简单) 2.字符串的最大公因子 (简单) 3.拥有最多糖果的孩子(简单) 4.种花问题(简单) 5.反转字符串中的元音字母(简单&a…...
【Unity - 屏幕截图】技术要点
在Unity中想要实现全屏截图或者截取某个对象区域的图片都是可以通过下面的函数进行截取 Texture2D/// <summary>/// <para>Reads the pixels from the current render target (the screen, or a RenderTexture), and writes them to the texture.</para>/…...
句句深刻,字字经典,创客匠人老蒋金句出炉,哪一句让你醍醐灌顶?
注意力经济时代、流量经济时代、短视频经济时代,创始人到底应该如何做,才能抓住风口,链接未来? 「创始人IP创新增长班」线下大课现场,老蒋作为主讲导师,再一次用他丰富的行业经验与深刻的时代洞察ÿ…...
柯尼卡美能达CA-310 FPD色彩分析仪
柯尼卡美能达CA-310 FPD色彩分析仪 型 号:CA-310 名 称:FPD色彩分析仪 品 牌:柯尼卡美能达(KONICA MINOLTA) 分 类:光学和色彩测试 > 光学、显示与色彩测量 > 色彩分析仪 产品属性:主机 简 述&…...
二维EKF的MATLAB代码
EKF二维滤波 MATLAB 实现 提升您的数据处理能力!本MATLAB程序实现了扩展卡尔曼滤波(EKF)在二维状态估计中的应用,专为需要高精度定位和动态系统分析的用户设计。通过精确的滤波技术,有效减少噪声影响,确保…...
大数据治理:数据时代的挑战与应对
目录 大数据治理:数据时代的挑战与应对 一、大数据治理的概念与内涵 二、大数据治理的重要性 1. 提高数据质量与可用性 2. 确保数据安全与合规 3. 支持数据驱动的决策 4. 提高业务效率与竞争力 三、大数据治理的实施策略 1. 建立健全的数据治理框架 2. 数…...
绿联NAS免驱安装MacOS
前段时间UGOS Pro迎来了一次大更新,Docker新增了Docker Compose堆栈项目,于是便在Docker Hub找了个支持Docker Compose部署的MacOS开源项目来验证一下,顺便体验一下用N100运行是什么感觉。 开始折腾 先说说,在没用Docker Compos…...
聊聊ASSERT处理在某些场景下的合理用法
先看看ASSERT的介绍: 编写代码时,我们总是会做出一些假设,ASSERT断言就是用于在代码中捕捉这些假设,可以将断言看作是异常处理的一种高级形式。断言表示为一些布尔表达式,程序员相信在程序中的某个特定点该表达式值为真…...
SAP Odata 服务
参考过程 SAP创建ODATA服务-Structure_sap odata-CSDN博客 案例...
【java数据结构】栈
【java数据结构】栈 一、栈的概念二、 栈的使用三、 栈的模拟实现(数组)构造方法size()empty()push()pop()peek() 四、 栈的模拟实现(链表)构造方法size()empty()push()pop()peek() 五、 栈的例题 此篇博客希望对你有所帮助(帮助你了解栈),不…...
从头开始的可视化数据 matplotlib:初学者努力绘制数据图
从头开始学习使用 matplotlib 可视化数据,对于初学者来说,可能会有些挑战,但 matplotlib 的核心理念非常清晰:绘制图表需要了解如何设置图形、坐标轴以及如何用数据填充它们。我们可以通过一些简单的例子来逐步介绍基本步骤。 1. …...
vscode 远程linux服务器 连接git
vscode 远程linux服务器 连接git 1. git 下载2. git 配置1)github 设置2)与github建立连接linux端:创建密钥github端:创建ssh key 3. 使用1)初始化repository2)commit 输入本次提交信息,提交到本…...
不同jdk版本中的接口规范
Java Development Kit(JDK)的每个版本通常会对 Java 语言和类库进行改进,接口规范也在不断演进。Java 接口的演变是逐步从 “纯粹抽象的定义” 向 “具有行为的抽象定义” 演化的。 JDK 1.0 和 JDK 1.1JDK 1.2 到 JDK 1.6JDK 1.8(…...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...
用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...
【C++】纯虚函数类外可以写实现吗?
1. 答案 先说答案,可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...
