flutter tabbar指示器indicator宽度高度自定义
在tabbar中indicator宽度是无法修改的,所以需要咱们去自定义indicator。
下面是自定义的代码,直接拷贝使用,已做好修改。
// Copyright 2018 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; /// Used with [TabBar.indicator] to draw a horizontal line below the /// selected tab. /// /// The selected tab underline is inset from the tab's boundary by [insets]. /// The [borderSide] defines the line's color and weight. /// /// The [TabBar.indicatorSize] property can be used to define the indicator's /// bounds in terms of its (centered) widget with [TabIndicatorSize.label], /// or the entire tab with [TabIndicatorSize.tab]. class TabSizeIndicator extends Decoration { final double wantWidth;//传入的指示器宽度,默认20 /// Create an underline style selected tab indicator. /// /// The [borderSide] and [insets] arguments must not be null. const TabSizeIndicator({ this.borderSide = const BorderSide(width: 2.0, color: Colors.blue), this.insets = EdgeInsets.zero, this.wantWidth = 20 }) : assert(borderSide != null), assert(insets != null), assert(wantWidth != null); /// The color and weight of the horizontal line drawn below the selected tab. final BorderSide borderSide;//指示器高度以及颜色 ,默认高度2,颜色蓝 /// Locates the selected tab's underline relative to the tab's boundary. /// /// The [TabBar.indicatorSize] property can be used to define the /// tab indicator's bounds in terms of its (centered) tab widget with /// [TabIndicatorSize.label], or the entire tab with [TabIndicatorSize.tab]. final EdgeInsetsGeometry insets; @override Decoration lerpFrom(Decoration a, double t) { if (a is UnderlineTabIndicator) { return UnderlineTabIndicator( borderSide: BorderSide.lerp(a.borderSide, borderSide, t), insets: EdgeInsetsGeometry.lerp(a.insets, insets, t), ); } return super.lerpFrom(a, t); } @override Decoration lerpTo(Decoration b, double t) { if (b is TabSizeIndicator) { return TabSizeIndicator( borderSide: BorderSide.lerp(borderSide, b.borderSide, t), insets: EdgeInsetsGeometry.lerp(insets, b.insets, t), ); } return super.lerpTo(b, t); } @override _MyUnderlinePainter createBoxPainter([ VoidCallback onChanged ]) { return _MyUnderlinePainter(this,wantWidth, onChanged); } } class _MyUnderlinePainter extends BoxPainter { final double wantWidth; _MyUnderlinePainter(this.decoration, this.wantWidth,VoidCallback onChanged) : assert(decoration != null), super(onChanged); final TabSizeIndicator decoration; BorderSide get borderSide => decoration.borderSide; EdgeInsetsGeometry get insets => decoration.insets; Rect _indicatorRectFor(Rect rect, TextDirection textDirection) { assert(rect != null); assert(textDirection != null); final Rect indicator = insets.resolve(textDirection).deflateRect(rect); //希望的宽度 // double wantWidth = 20; //取中间坐标 double cw = (indicator.left + indicator.right) / 2; return Rect.fromLTWH(cw - wantWidth / 2, indicator.bottom - borderSide.width, wantWidth, borderSide.width); } @override void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) { assert(configuration != null); assert(configuration.size != null); final Rect rect = offset & configuration.size; final TextDirection textDirection = configuration.textDirection; final Rect indicator = _indicatorRectFor(rect, textDirection).deflate(borderSide.width / 2.0); final Paint paint = borderSide.toPaint()..strokeCap = StrokeCap.square; canvas.drawLine(indicator.bottomLeft, indicator.bottomRight, paint); } }
将源码拷贝过来进行修改。以上代码就是修改好的。下面是使用方式。
TabBar( indicator: TabSizeIndicator(wantWidth: 15,borderSide: BorderSide(width: 2.0,color: Colors.red)),//TabSizeIndicator已有默认值,宽度默认20,颜色蓝色,高度2,不需要修改的可以不传参数
//TabSizeIndicator();即可 isScrollable: true, controller: _tabController, unselectedLabelStyle: TextStyle( fontSize: 13, fontWeight: FontWeight.bold), labelStyle: TextStyle( fontWeight: FontWeight.bold, fontSize: 13), tabs:_tabbarItem() ),