Search code examples
flutterflutter-layout

Flutter arrow tab bar?


How I can make the cursor of tab bar with an arrow like this? enter image description here


Solution

  • You can achieve your desire indicator using custom painter and 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);
      }
    }