繁体   English   中英

有没有办法让标签栏指示器线在颤动中呈现渐变?

[英]Is there a way to make the tab bar indicator line a gradient in flutter?

我正在尝试创建一个具有渐变下划线的 TabBar,如下图所示。 带有渐变下划线的图像

我尝试按照之前的帖子的建议使用 BoxDecoration,但它并没有完全按照我的意愿显示。

TabBar(
        labelColor: Theme.of(context).primaryColor,
        indicator: BoxDecoration(
          gradient: LinearGradient(
  colors: const [Color(0xFF10C7E0), Color(0xFF00D5C3)],
),
        ),
        tabs: ...,
      ),

当我尝试这样做时,我得到的是![我的 TabBar 图片](https://pasteboard.co/Iu42o3e.png)

有人指出,这篇文章是 10 个月前发布的how-to-give-a-gradient-line-in-tab-bar-indicator的重复。 但是那里说明的方法不再有效。 是的,我试过了。

这个选项有什么问题? (基于链接中的代码)

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: DefaultTabController(
        length: 2,
        child: Scaffold(
          appBar: AppBar(
            title: Text('All', style: TextStyle(color: const Color(0xff596173))),
            backgroundColor: Colors.white,
            centerTitle: true,
            bottom: TabBar(
              labelColor: const Color(0xff525c6e),
              unselectedLabelColor: const Color(0xffacb3bf),
              indicatorPadding: EdgeInsets.all(0.0),
              indicatorWeight: 4.0,
              labelPadding: EdgeInsets.only(left: 0.0, right: 0.0),
              indicator: ShapeDecoration(
                  shape: UnderlineInputBorder(
                      borderSide: BorderSide(color: Colors.transparent, width: 0, style: BorderStyle.solid)),
                  gradient: LinearGradient(colors: [Color(0xff0081ff), Color(0xff01ff80)])),
              tabs: <Widget>[
                Container(
                  height: 40,
                  alignment: Alignment.center,
                  color: Colors.white,
                  child: Text("Visual"),
                ),
                Container(
                  height: 40,
                  alignment: Alignment.center,
                  color: Colors.white,
                  child: Text("Tabular"),
                ),
              ],
            ),
          ),
          body: Container(color: Colors.grey[200]),
        ),
      ),
    );
  }
}

在此处输入图片说明

尝试将其替换为以下内容:

指示器:容器(对齐方式:Alignment.bottomCenter,子代:容器(高度:8.0装饰:BoxDecoration(...))

从我的iPhone发布

您可以通过修改默认的UnderlineTabIndicator创建自己的指标。

import 'package:flutter/material.dart';

class CustomUnderlineTabIndicator extends Decoration {
  /// Create an underline style selected tab indicator.
  ///
  /// The [borderSide] and [insets] arguments must not be null.
  const CustomUnderlineTabIndicator({
    this.gradient,
    this.insets = EdgeInsets.zero,
    this.borderSide = const BorderSide(width: 2.0, color: Colors.white),
  });

  /// The color and weight of the horizontal line drawn below the selected tab.
  final BorderSide borderSide;

  final Gradient? gradient;

  /// 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 CustomUnderlineTabIndicator) {
      return CustomUnderlineTabIndicator(
        gradient: Gradient.lerp(a.gradient, gradient, t),
        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 CustomUnderlineTabIndicator) {
      return CustomUnderlineTabIndicator(
        gradient: Gradient.lerp(gradient, b.gradient, t),
        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 _CustomUnderlinePainter(this, onChanged);
  }

  Rect _indicatorRectFor(Rect rect, TextDirection textDirection) {
    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 _CustomUnderlinePainter extends BoxPainter {
  _CustomUnderlinePainter(this.decoration, VoidCallback? onChanged)
      : super(onChanged);

  final CustomUnderlineTabIndicator 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 = StrokeCap.square;
    paint.shader =
        decoration.gradient?.createShader(rect, textDirection: textDirection);
    canvas.drawLine(indicator.bottomLeft, indicator.bottomRight, paint);
  }
}

刚刚复制了UnderlineTabIndicator并为其添加了渐变。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM