| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- import 'package:flutter/material.dart';
- /// 自定义Tab的指示器
- class CustomTabIndicator extends Decoration {
- /// Create an underline style selected tab indicator.
- ///
- /// The [borderSide] and [insets] arguments must not be null.
- const CustomTabIndicator({
- this.width = 20,
- this.strokeCap = StrokeCap.round,
- this.borderSide = const BorderSide(width: 2.0, color: Colors.white),
- this.insets = EdgeInsets.zero,
- });
- /// The color and weight of the horizontal line drawn below the selected tab.
- final BorderSide borderSide;
- /// 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
- /// [TabBarIndicatorSize.label], or the entire tab with
- /// [TabBarIndicatorSize.tab].
- final EdgeInsetsGeometry insets;
- /// 新增属性:控制器宽度
- final double width;
- /// 新增属性:控制器边角形状
- final StrokeCap strokeCap;
- @override
- Decoration? lerpFrom(Decoration? a, double t) {
- if (a is CustomTabIndicator) {
- return CustomTabIndicator(
- 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 CustomTabIndicator) {
- return CustomTabIndicator(
- borderSide: BorderSide.lerp(borderSide, b.borderSide, t),
- insets: EdgeInsetsGeometry.lerp(insets, b.insets, t)!,
- );
- }
- return super.lerpTo(b, t);
- }
- @override
- BoxPainter createBoxPainter([VoidCallback? onChanged]) {
- return _UnderlinePainter(this, onChanged);
- }
- /// 决定控制器宽度的方法
- Rect _indicatorRectFor(Rect rect, TextDirection textDirection) {
- final Rect indicator = insets.resolve(textDirection).deflateRect(rect);
- // 希望的宽度
- double wantWidth = width;
- // 取中间坐标
- double cw = (indicator.left + indicator.right) / 2;
- // 下划线靠左
- // return Rect.fromLTWH(indicator.left,
- // indicator.bottom - borderSide.width, wantWidth, borderSide.width);
- //下划线居中
- return Rect.fromLTWH(
- cw - wantWidth / 2,
- indicator.bottom - borderSide.width,
- wantWidth,
- borderSide.width,
- );
- }
- @override
- Path getClipPath(Rect rect, TextDirection textDirection) {
- return Path()..addRect(_indicatorRectFor(rect, textDirection));
- }
- }
- class _UnderlinePainter extends BoxPainter {
- _UnderlinePainter(this.decoration, VoidCallback? onChanged)
- : super(onChanged);
- final CustomTabIndicator decoration;
- /// 决定控制器边角形状的方法
- @override
- void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
- assert(configuration.size != null);
- final Rect rect = offset & configuration.size!;
- final TextDirection textDirection = configuration.textDirection!;
- final Rect indicator = decoration
- ._indicatorRectFor(rect, textDirection)
- .deflate(decoration.borderSide.width / 2.0);
- final Paint paint =
- decoration.borderSide.toPaint()..strokeCap = decoration.strokeCap;
- canvas.drawLine(indicator.bottomLeft, indicator.bottomRight, paint);
- }
- }
|