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(…...

人工智能图像信号处理器(AI ISP)技术介绍
随着智能设备和数码成像技术的快速发展,图像质量的提升成为用户体验的关键因素之一。人工智能图像信号处理器(AI Image Signal Processor,AI ISP) 作为传统图像信号处理器(ISP)的升级版,通过集成…...

3D Slicer 教程三 ---- 坐标系
上篇提到3D Slicer 教程二 ---- 数据集-CSDN博客 3d slicer的坐标系与大多数医学影像软件使用LPS(左、后、上)坐标系统不太一样, 今天就仔细介绍一下坐标系的区别,复盘一下在影像处理中遇到的坐标问题(集中在坐标处理相关的,图像插值,图像处理, 定位线,翻…...

Video-LLaMA论文解读和项目部署教程
Video-LLaMA: An Instruction-tuned Audio-Visual Language Model for Video Understanding 相关工作 大型语言模型: 本文的工作基于这些LLM,并提供即插即用插件,使其能够理解视频中的视觉和听觉内容。 多模态大型语言模型: 现有…...

Elasticsearch设置 X-Pack认证,设置账号和密码
前言 以下Elasticsearch版本:7.9.3 ES自带的X-Pack密码验证: X-Pack是elasticsearch的一个扩展包,将安全,警告,监视,图形和报告功能捆绑在一个易于安装的软件包中,所以我们想要开启账号密码验证…...

机器学习——量子机器学习(Quantum Machine Learning)
机器学习——量子机器学习(Quantum Machine Learning) 量子机器学习(Quantum Machine Learning)——未来的智能计算量子机器学习的核心概念使用Qiskit进行量子机器学习——代码示例代码解析量子机器学习的应用结论 量子机器学习&a…...

Android Studio 的 Gradle 任务列表只显示测试任务
问题现象如下: 问题原因: 这是因为Android Studio 设置中勾选了屏蔽其他gradle任务的选项。 解决方法: File -> Settings -> Experimental 取消勾选Only include test tasks in the Gradle task list generated during Gradle Sync&…...

Keepalived:高可用性的守护神
Keepalived:高可用性的守护神 在现代企业IT系统中,高可用性是确保业务连续性和服务质量的关键要素。系统面对硬件故障、软件错误、人为失误或自然灾害时,依然能保持正常运行,这样的能力对于企业来说至关重要。为此,业界开发了一系列高可用性解决方案,其中Keepalived以其…...

Golang笔记_day08
Go面试题(一) 1、空切片 和 nil 切片 区别 空切片: 空切片是指长度和容量都为0的切片。它不包含任何元素,但仍然具有切片的容量属性。在Go语言中,可以使用内置的make函数创建一个空切片,例如:…...

如何在 React 中更新状态对象的某个值
在 React 中,我们经常需要更新组件的状态来反映 UI 的变化。如果状态是一个复杂的对象,比如一个包含多个筛选条件的对象,我们希望只更新其中的某个键,而不是整个状态对象。今天,我将向大家展示如何在更新状态时保留已有…...

edge浏览器:你的连接不是专用连接
最近在使用edge浏览器打开github时,发现打不开了,提升你的连接不是专用连接。试了很多种方法甚至重装了浏览器,都没有用。 直到看到了这篇文章,才得到解决: 10 个修复此站点在 Windows Edge 上的连接不安全的问题htt…...