Flutter 自定义TabBar指示器(indicator)实现秒杀UI样式
一、话不多说,先来看下实现的交互效果,源码在文末
二、首先分解一下需求
- 自定义Tab指示器与Tab
- 当秒杀节点小于5个的时候,每一个Tab的宽度为平分屏幕宽度
- 当大于等于5个的时候,每一个Tab的宽度为固定宽度
1、先来看下最简单的TabBar与TabBarView需要如何实现
/// 省略若干代码...
@override
Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('TabBar'),bottom: TabBar(controller: _tabController,tabs: [Tab(text: "热销"),Tab(text: "推荐"),Tab(text: "我的"),],),),body: TabBarView(controller: _tabController,children: [Center(child: Text('热销')),Center(child: Text('推荐')),Center(child: Text('我的')),],),);
}
上面代码实现的效果
2、通过阅读TabBar
的源码可以知道tabs
属性接收widget
集合,这也就是我们自定义Tab的突破口了
/// Typically a list of two or more [Tab] widgets.
///
/// The length of this list must match the [controller]'s [TabController.length]
/// and the length of the [TabBarView.children] list.
final List<Widget> tabs;
三、通过画图来分析一下整个Tab的层级结构
- 白色层:就是
TabBar
所占的高度(Tab高度+三角箭头高度) - 灰色层:就是每一个
Tab
所占的高度 - 红色层:就是自定义的
TabBar indicator
1、通过上面的图我们需要定义如下一些数据:
- 每个Tab的宽度和高度
double _tabWidth = 82.0;
double _tabHeight = 70.0;
- 三角形的宽高
Size triangleSize = Size(10, 10);
2、每一个Tab
通过Container
组件来实现
class FlashSale extends StatefulWidget {@overrideFlashSaleState createState() => new FlashSaleState();
}
class FlashSaleState extends State<FlashSale>with SingleTickerProviderStateMixin {TabController _tabController;List<String> _list;double _tabWidth = 82.0;double _tabHeight = 70.0;///定义三角的大小Size triangleSize = Size(10, 10);@overridevoid initState() {super.initState();_list = ['10:00', '11:00', '12:00', '13:00', '14:00'];_tabController =TabController(initialIndex: 0, length: _list.length, vsync: this);}@overrideWidget build(BuildContext context) {return Scaffold(///省略....body: Column(children: [TabBar(isScrollable: true,controller: _tabController,tabs: _list.map((e) {return _tab(e);}).toList(),)///省略TabBarView内容...],),);}Widget _tab(String content) {return Container(width: _tabWidth,height: _tabHeight + triangleSize.height,child: Padding(padding: EdgeInsets.only(bottom: triangleSize.height),child: Column(mainAxisAlignment: MainAxisAlignment.center,children: [Text(content,style: TextStyle(color: Colors.white, fontSize: 22),),Text('抢购中',style: TextStyle(color: Colors.white, fontSize: 14),)],),),);}}
Container的高度就是上面说到的,需要加上三角形的高度;如下效果图
这里文字需要剧中,所以需要padding bottom 三角形的高度
3、现在就需要给每一个Tab
添加灰色未选中的颜色了;很容易想到是加在Container
中的,但是加在这里是有问题的我们需要把这个灰色加在TabBar
这里;但是现在我们TabBar的高度=Tab高度 + 三角箭头高度
所以加在这里会使得三角箭头区域也是灰色,那这样需要怎么处理呢?解决方法如下
- 通过
Stack
布局方式在TabBar
底部层叠个灰色的Container
///省略....
@override
Widget build(BuildContext context) {return Scaffold(///省略....body: Column(children: [Stack(children: [Container(width: double.infinity,height: _tabHeight,color: Color(0xFF4D525C),),TabBar(isScrollable: true,controller: _tabController,tabs: _list.map((e) {return _tab(e);}).toList(),)],)///省略TabBarView内容...],),);
}
四、现在重要的一步就是自定义TabBar
的indicator
,通过源码可知是一个Decoration
对象,所以我们只需继承它即可
1、一个继承Decoration
最基本的结构就是下面的样子了
class TriangleIndicator extends Decoration {//三角形的大小final Size triangleSize;TriangleIndicator(this.triangleSize);@overrideBoxPainter createBoxPainter([VoidCallback onChanged]) {return _CustomBoxPainter(triangleSize);}
}class _CustomBoxPainter extends BoxPainter {final Size triangleSize;_CustomBoxPainter(this.triangleSize);@overridevoid paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {}
}
- 然后在
TabBar
处使用即可
//省略其它...
TabBar(isScrollable: true,controller: _tabController,indicator: TriangleIndicator(triangleSize),tabs: _list.map((e) {return _tab(e);}).toList(),
)
2、接下来就只需要在paint
函数中将选中的Tab样式绘制出来即可(写过Android自定义View看着就会显的很亲切了)
- 绘制矩形
@override
void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {///每个Tab的宽高Size tabSize = Size(configuration.size.width,configuration.size.height - triangleSize.height);final Rect rect = offset & tabSize;final Paint paint = Paint();paint.color = Color(0xFFFF443D);paint.style = PaintingStyle.fill;///画Tab矩形canvas.drawRect(rect, paint);
}
offset
参数:意思当前位置距离组建左上角的偏移量configuration
参数:当前画布的大小
- 从图中发现绘制的高度减去了三角形区域的高度,可还是多出了一点,这是为什么呢?原因是
TabBar的indicator
默认给了高度为2,只需要将它设置为0即可
TabBar(//省略....indicatorWeight: 0,
)
- 绘制三角形,这里通过
Path
来绘制,也就是三角形的起点、中点、终点
连接起来
@override
void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {///每个Tab的宽高Size tabSize = Size(configuration.size.width,configuration.size.height - triangleSize.height);final Rect rect = offset & tabSize;final Paint paint = Paint();paint.color = Color(0xFFFF443D);paint.style = PaintingStyle.fill;///画Tab矩形canvas.drawRect(rect, paint);///画三角形double start = (tabSize.width - triangleSize.width) / 2;Path trianglePath = Path();///起点trianglePath.moveTo(start + offset.dx, configuration.size.height - triangleSize.height);///中点trianglePath.lineTo((tabSize.width / 2) + offset.dx, configuration.size.height);///终点trianglePath.lineTo(start + offset.dx + triangleSize.width,configuration.size.height - triangleSize.height);canvas.drawPath(trianglePath, paint);
}
五、最后一条需求动态改变每个Tab
的宽高,这个也很简单:只需要判断当前有几个Tab然后动态计算即可,直接查看源码即可
本篇源码下载地址
Flutter 自定义TabBar指示器(indicator)实现秒杀UI样式相关推荐
- 微信小程序自定义tabbar导航栏,中间凸出样式
这种样式的底部导航栏 使用微信小程序的自定义tabBar:微信小程序官方说明 uni.app=>在 page.json 中的 tabBar 项指定 custom 字段为true: "t ...
- flutter 自定义Tabbar高度和背景色
最近在学习flutter相关的知识,在学到Tabbar的时候默认无法修改它的高度背景色,在网上查看被人的代码后自己封装了一下.你可以复制直接使用.(不排除有更好的实现方法,我也是刚接触flutter) ...
- Flutter自定义 TabBar
TabBar常用于放在AppBar中,以标签页的形式展示同一个页面不同内容的主题标签. 常见的属性如下: 1. tabs 标签组: 2. controller 标签控制器: 3. isScrollab ...
- 小程序(三)配置tabbar及自定义tabbar样式
关于tabbar部分,官方文档是有明确的说明的,当然,我这里是不存在把官方文档给你复制一遍的情况.我大概把我再看官方文档过程中遇到的坑,大概复述一下. 一:配置tabbar 这个主要是使用小程序自带的 ...
- Flutter 组件之 Flutter高级自定义TabBar(教程含源码)
实战需求 Flutter 组件之 Flutter高级自定义TabBar(教程含源码) 本文价值与收获 看完本文后,您将能够作出下面的界面 实战代码 import 'package:flutter/ma ...
- React Native ScrollableTabView的自定义tabBar
react-native-scrollable-tab-view是一个非常好用的TabBar组件,支持滑动,可以实现标签超过屏幕宽度的情况.但是有时会需要实现比如提示未读个数.定制样式这些需求,那么已 ...
- 微信小程序 五 npm 包 、安装 vant组件、promise组件、全局数据共享、 分包!!!、自定义 tabBar 案例
总结 能够知道如何安装和配置 vant-weapp 组件库 参考 Vant 的官方文档 能够知道如何使用 MobX 实现全局数据共享 安装包.创建 Store.参考官方文档进行使用 能够知道如何对小程 ...
- 微信小程序 - 进阶(自定义组件、promis化、mobx、分包、自定义tabBar)
文章目录 一.自定义组件 1.创建组件 2.引用组件 3.组件和页面区别 4.组件样式 5.data.methods.properties 6.小程序的 data 和 properties 区别 7. ...
- 二、TabLayout自定义图片指示器
最近项目需求,多个tab切换显示不同的页面,但是tab的下划线是一个带有圆角阴影的下划线,看过Tablayout源码的小伙伴可能会知道,通过原生的TabLayout是无法实现的,想了解的可以看我的另一 ...
- 小程序自定义tabbar踩坑笔记
最近在给客户做一个定制小程序,客户不喜欢小程序自带的tabbar,想要一个炫酷的异形的tabbar,翻看了小程序开发者文档是可以执行的. 参考官方网站,自定义tabBar 自定义 tabBar | 微 ...
最新文章
- directx 游戏模拟键盘输入
- 牛客小白月赛6 H 挖沟
- boost::mpl::min和boost::mpl::max相关的测试程序
- QT绘制堆叠水平条形图
- implementation of CreateBindingContext
- C++中堆和栈的完全解析
- 企业级实战03_真实项目实战SpringMVC整合ActiveMQ
- SQL安装文件挂起解决方法
- 时序数据库php,时序数据库InfluxDB
- 新手进阶:LoadRunner中Pacing的设置
- 软件观念革命:交互设计精髓_2021年中国传媒大学设计学考研招生分析、参考书目、复试线、真题回忆、考研经验指南篇...
- 苹果悬浮球_手机轻松实现多个系统!安卓手机运行苹果iOS系统?期待!
- ShineDisk M667固态修复记录 慧荣SM2258XT开卡量产工具
- 利用数据质量规则库推动数据质量管理
- 手机wps怎么设置打印横竖_WPS中横竖打印怎么设置
- 什么是语法糖(Syntactic sugar)?
- jpa报错:mappedBy reference an unknown target entity property:
- Kotlin 非对称加密RSA
- wireshark 抓包使用教程
- Arduino 浊度传感器 TS300B 的使用