美文网首页
flutter-实现一个圆角指示器(下划线)的TabBar

flutter-实现一个圆角指示器(下划线)的TabBar

作者: 浮华_du | 来源:发表于2021-06-18 14:21 被阅读0次
    image.png

    查看UnderlineTabIndicator发现,底部的指示器是通过_UnderlinePainter画笔划了一条线.
    下面我们直接把这个画笔改成圆角的就可以咯~

    
    ///参考UnderlineTabIndicator,仅仅修改画笔StrokeCap.square 为 StrokeCap.round
    class CustomUnderlineTabIndicator extends Decoration {
      /// Create an underline style selected tab indicator.
      ///
      /// The [borderSide] and [insets] arguments must not be null.
      const CustomUnderlineTabIndicator({
        this.borderSide = const BorderSide(width: 2.0, color: Colors.white),
        this.insets = EdgeInsets.zero,
      })  : 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;
    
      @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 UnderlineTabIndicator) {
          return UnderlineTabIndicator(
            borderSide: BorderSide.lerp(borderSide, b.borderSide, t),
            insets: EdgeInsetsGeometry.lerp(insets, b.insets, t)!,
          );
        }
        return super.lerpTo(b, t);
      }
    
      @override
      _UnderlinePainter 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);
        return Rect.fromLTWH(
          indicator.left,
          indicator.bottom - borderSide.width,
          indicator.width,
          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 CustomUnderlineTabIndicator? decoration;
    
      BorderSide? get borderSide => decoration?.borderSide;
    
      EdgeInsetsGeometry? get insets => decoration?.insets;
    
      @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();
        paint.strokeWidth = 5;
        paint.strokeCap = StrokeCap.round; //主要是修改此处  圆角
        canvas.drawLine(indicator.bottomLeft, indicator.bottomRight, paint);
      }
    }
    

    然后再Tabbar中指定这个CustomUnderlineTabIndicator

    TabBar(
          indicatorWeight: 5,
          indicatorSize: TabBarIndicatorSize.label,
          indicator: CustomUnderlineTabIndicator(
            insets: EdgeInsets.only(top: 10.w, bottom: 2.w),
            borderSide: BorderSide(width: 5.w, color: Colors.red),
          ),
          // indicator: BoxDecoration(
          //     borderRadius: BorderRadius.circular(3.5.w),
          //     gradient: LinearGradient(
          //       begin: Alignment.centerLeft,
          //       end: Alignment.centerRight,
          //       colors: [Color(0xff54C9FF), Colors.blue],
          //     )),
          controller: _tabController,
          tabs: _tabList.map((str) {
            return Container(
              height: 50,
              color: Colors.white,
              child: Center(
                child: new Text(
                  str,
                  style: TextStyle(color: Colors.black, fontSize: 25.sp),
                ),
              ),
            );
          }).toList(),
        )
    

    喜欢的话,帮忙点赞哦~

    相关文章

      网友评论

          本文标题:flutter-实现一个圆角指示器(下划线)的TabBar

          本文链接:https://www.haomeiwen.com/subject/zlikyltx.html