欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 会展 > flutter TabBar自定义指示器(带文字的指示器、上弦弧形指示器、条形背景指示器、渐变色的指示器)

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

2024/10/24 12:47:22 来源:https://blog.csdn.net/androidhyf/article/details/143023772  浏览:    关键词: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,)

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com