123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- // Copyright 2014 The Flutter 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';
- /// 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 [TabBarIndicatorSize.label],
- /// or the entire tab with [TabBarIndicatorSize.tab].
- class RoundUnderlineTabIndicator extends Decoration {
- /// Create an underline style selected tab indicator.
- ///
- /// The [borderSide] and [insets] arguments must not be null.
- const RoundUnderlineTabIndicator({
- this.borderSide = const BorderSide(width: 2.0, color: Colors.white),
- this.insets = EdgeInsets.zero,
- this.width = 26.0,
- }) : assert(borderSide != null),
- assert(insets != null);
- /// 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;
- @override
- Decoration? lerpFrom(Decoration? a, double t) {
- if (a is RoundUnderlineTabIndicator) {
- return RoundUnderlineTabIndicator(
- 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 RoundUnderlineTabIndicator) {
- return RoundUnderlineTabIndicator(
- 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) {
- assert(rect != null);
- assert(textDirection != null);
- final Rect indicator = insets.resolve(textDirection).deflateRect(rect);
- if (width == 0) {
- return Rect.fromLTWH(
- indicator.left,
- indicator.bottom - borderSide.width,
- indicator.width,
- borderSide.width,
- );
- } else {
- return Rect.fromCenter(center: Offset(rect.center.dx, indicator.bottom - borderSide.width), width: 26, height: borderSide.width);
- }
- }
- @override
- Path getClipPath(Rect rect, TextDirection textDirection) {
- return Path()..addRect(_indicatorRectFor(rect, textDirection));
- }
- }
- class _UnderlinePainter extends BoxPainter {
- _UnderlinePainter(this.decoration, VoidCallback? onChanged)
- : assert(decoration != null),
- super(onChanged);
- final RoundUnderlineTabIndicator decoration;
- @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 = decoration._indicatorRectFor(rect, textDirection).deflate(decoration.borderSide.width / 2.0);
- final Paint paint = decoration.borderSide.toPaint()..strokeCap = StrokeCap.round;
- canvas.drawLine(indicator.bottomLeft, indicator.bottomRight, paint);
- }
- }
|