繁体   English   中英

Flutter 箭头标签栏?

[英]Flutter arrow tab bar?

我如何用这样的箭头制作标签栏的 cursor?在此处输入图像描述

您可以使用自定义画家和 tabindicator 来实现您的愿望指示器。

import 'package:flutter/material.dart';

class Delete extends StatefulWidget {
  Delete({Key key}) : super(key: key);

  @override
  _DeleteState createState() => _DeleteState();
}

class _DeleteState extends State<Delete> with SingleTickerProviderStateMixin {
  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 3,
      child: Scaffold(
        appBar: AppBar(
          bottom: TabBar(
            indicatorSize: TabBarIndicatorSize.tab,
            indicator: CircleTabIndicator(color: Colors.orange),
            tabs: <Widget>[
              Tab(
                child: Text(
                  'fruits',
                ),
              ),
              Tab(
                child: Text(
                  'vegetables',
                ),
              ),
              Tab(
                child: Text(
                  'berries',
                ),
              ),
            ],
          ),
        ),
        body: TabBarView(
          children: <Widget>[
            Center(child: Text('Tab 1')),
            Center(child: Text('Tab 2')),
            Center(child: Text('Tab 3')),
          ],
        ),
      ),
    );
  }
}

class CircleTabIndicator extends Decoration {
  final BoxPainter _painter;

  CircleTabIndicator({@required Color color})
      : _painter = _CirclePainter(color);

  @override
  BoxPainter createBoxPainter([onChanged]) => _painter;
}

class _CirclePainter extends BoxPainter {
  final Paint _paint;

  _CirclePainter(Color color)
      : _paint = Paint()
          ..color = color
          ..isAntiAlias = true;

  @override
  void paint(Canvas canvas, Offset offset, ImageConfiguration cfg) {
    Path _trianglePath = Path();

    _trianglePath.moveTo(cfg.size.width / 2 - 10, cfg.size.height);
    _trianglePath.lineTo(cfg.size.width / 2 + 10, cfg.size.height);
    _trianglePath.lineTo(cfg.size.width / 2, cfg.size.height - 10);
    _trianglePath.lineTo(cfg.size.width / 2 - 10, cfg.size.height);
    _trianglePath.close();
    canvas.drawPath(_trianglePath, _paint);
  }
}

基于 Virens 的回答,我制作了这个版本的画家,它解决了评论中的问题,并且 null 可以安全地与 Flutter 的较新版本一起使用。

它还可以更清楚地说明 paint 方法中发生的事情。

import 'package:flutter/material.dart';

class ArrowTabBarIndicator extends Decoration {
  final BoxPainter _painter;
  ArrowTabBarIndicator({double width = 20, double height = 10})
      : _painter = _ArrowPainter(width, height);

  @override
  BoxPainter createBoxPainter([VoidCallback? onChanged]) => _painter;
}

class _ArrowPainter extends BoxPainter {
  final Paint _paint;
  final double width;
  final double height;

  _ArrowPainter(this.width, this.height)
      : _paint = Paint()
    ..color = Colors.white
    ..isAntiAlias = true;

  @override
  void paint(Canvas canvas, Offset offset, ImageConfiguration cfg) {
    Path _trianglePath = Path();
    if (cfg.size != null){

      Offset centerTop = Offset(cfg.size!.width / 2, cfg.size!.height - height) + offset;
      Offset bottomLeft = Offset(cfg.size!.width / 2 - (width/2), cfg.size!.height) + offset;
      Offset bottomRight = Offset(cfg.size!.width / 2 + (width/2), cfg.size!.height) + offset;

      _trianglePath.moveTo(bottomLeft.dx, bottomLeft.dy);
      _trianglePath.lineTo(bottomRight.dx, bottomRight.dy);
      _trianglePath.lineTo(centerTop.dx, centerTop.dy);
      _trianglePath.lineTo(bottomLeft.dx, bottomLeft.dy);

      _trianglePath.close();
      canvas.drawPath(_trianglePath, _paint);
  }
  }
}

原始答案的主要问题是它没有考虑在这种情况下控制指标绘制在哪个选项卡下的“偏移”参数。

暂无
暂无

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

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