Tab In Flutter

Tab In Flutter :

Screenshot :

Tab In Flutter

Program :

main.dart

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter/cupertino.dart';
import 'bubble_tab_indicator.dart';

void main() {
   runApp(new MaterialApp(
     debugShowCheckedModeBanner: false,
     home: new TabDemo(),
   ));
 }
class TabDemo extends StatefulWidget {
   @override
   _TabDemoState createState() => new _TabDemoState();
 }
class _TabDemoState extends State with SingleTickerProviderStateMixin {
   TabController tabController;
   TextStyle tabStyle = TextStyle(fontSize: 16);

@override
   void initState() {
     super.initState();
     tabController = TabController(length: 3, vsync: this, initialIndex: 0);
   }

@override
   Widget build(BuildContext context) {
     return tabCreate();
   }

tabCreate() => DefaultTabController(
       length: 3,
       child: new Scaffold(
           appBar: new AppBar(
             title: new Text("Flutter Tab"),
             bottom: TabBar(
               /* indicator: BoxDecoration(
                     color: Colors.white,
                     borderRadius: BorderRadius.circular(50.0)
                 ),*/
               indicator: new BubbleTabIndicator(
                 indicatorHeight: 40.0,
                 indicatorColor: Colors.orange.shade50,
                 tabBarIndicatorSize: TabBarIndicatorSize.tab,
               ),
               //indicatorColor: Colors.black54,
               labelColor: Colors.orangeAccent,
               unselectedLabelColor: Colors.white,
               controller: tabController,
               isScrollable: false,
               tabs: [
                 //TODO TAB NAME PICKUP, DISPATCH, POSTPONE
                 tabName('Flutter'),
                 tabName('Android'),
                 tabName('Kotlin'),
               ],
             ),
           ),
           body: TabBarView(controller: tabController, children: [
             //TODO TAB SLIDING
             new Container(child: Text('Flutter')),
             new Container(child: Text('Android')),
             new Container(child: Text('Kotlin')),
           ])));

tabCreate() => DefaultTabController(
       length: 3,
       child: new Scaffold(
           appBar: new AppBar(
             title: new Text("Flutter Tab"),
             bottom: TabBar(
               /* indicator: BoxDecoration(
                     color: Colors.white,
                     borderRadius: BorderRadius.circular(50.0)
                 ),*/
               indicator: new BubbleTabIndicator(
                 indicatorHeight: 40.0,
                 indicatorColor: Colors.orange.shade50,
                 tabBarIndicatorSize: TabBarIndicatorSize.tab,
               ),
               //indicatorColor: Colors.black54,
               labelColor: Colors.orangeAccent,
               unselectedLabelColor: Colors.white,
               controller: tabController,
               isScrollable: false,
               tabs: [
                 //TODO TAB NAME PICKUP, DISPATCH, POSTPONE
                 tabName('Flutter'),
                 tabName('Android'),
                 tabName('Kotlin'),
               ],
             ),
           ),
           body: TabBarView(controller: tabController, children: [
             //TODO TAB SLIDING
             new Container(child: Text('Flutter')),
             new Container(child: Text('Android')),
             new Container(child: Text('Kotlin')),
           ])));

@override
   void dispose() {
     tabController.dispose();
     super.dispose();
   }

tabName(String name) => Tab(
         child: Text(
           name,
           style: tabStyle,
         ),
       );
 }

bubble_tab_indicator.dart

library flutter_bubble_tab_indicator;
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';

class BubbleTabIndicator extends Decoration {
   final double indicatorHeight;
   final Color indicatorColor;
   final double indicatorRadius;
   final EdgeInsetsGeometry padding;
   final EdgeInsetsGeometry insets;
   final TabBarIndicatorSize tabBarIndicatorSize;

const BubbleTabIndicator({
     this.indicatorHeight: 20.0,
     this.indicatorColor: Colors.greenAccent,
     this.indicatorRadius: 100.0,
     this.tabBarIndicatorSize = TabBarIndicatorSize.label,
     this.padding: const EdgeInsets.symmetric(vertical: 2.0, horizontal: 8.0),
     this.insets: const EdgeInsets.symmetric(horizontal: 5.0),
   })  : assert(indicatorHeight != null),
         assert(indicatorColor != null),
         assert(indicatorRadius != null),
         assert(padding != null),
         assert(insets != null);
@override
   Decoration lerpFrom(Decoration a, double t) {
     if (a is BubbleTabIndicator) {
       return new BubbleTabIndicator(
         padding: EdgeInsetsGeometry.lerp(a.padding, padding, t),
         insets: EdgeInsetsGeometry.lerp(a.insets, insets, t),
       );
     }
     return super.lerpFrom(a, t);
   }
@override
   Decoration lerpTo(Decoration b, double t) {
     if (b is BubbleTabIndicator) {
       return new BubbleTabIndicator(
         padding: EdgeInsetsGeometry.lerp(padding, b.padding, t),
         insets: EdgeInsetsGeometry.lerp(insets, b.insets, t),
       );
     }
     return super.lerpTo(b, t);
   }
@override
   Decoration lerpTo(Decoration b, double t) {
     if (b is BubbleTabIndicator) {
       return new BubbleTabIndicator(
         padding: EdgeInsetsGeometry.lerp(padding, b.padding, t),
         insets: EdgeInsetsGeometry.lerp(insets, b.insets, t),
       );
     }
     return super.lerpTo(b, t);
   }
class _BubblePainter extends BoxPainter {
   _BubblePainter(this.decoration, VoidCallback onChanged)
       : assert(decoration != null),
         super(onChanged);
final BubbleTabIndicator decoration;
double get indicatorHeight => decoration.indicatorHeight;
   Color get indicatorColor => decoration.indicatorColor;
   double get indicatorRadius => decoration.indicatorRadius;
   EdgeInsetsGeometry get padding => decoration.padding;
   EdgeInsetsGeometry get insets => decoration.insets;
   TabBarIndicatorSize get tabBarIndicatorSize => decoration.tabBarIndicatorSize;
Rect _indicatorRectFor(Rect rect, TextDirection textDirection) {
     assert(rect != null);
     assert(textDirection != null);
Rect indicator = padding.resolve(textDirection).inflateRect(rect);

if (tabBarIndicatorSize == TabBarIndicatorSize.tab) {
  indicator = insets.resolve(textDirection).deflateRect(rect);
}

return new Rect.fromLTWH(
  indicator.left,
  indicator.top,
  indicator.width,
  indicator.height,
);
}
@override
   void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
     assert(configuration != null);
     assert(configuration.size != null);
     final Rect rect = Offset(
             offset.dx, (configuration.size.height / 2) - indicatorHeight / 2) &
         Size(configuration.size.width, indicatorHeight);
     final TextDirection textDirection = configuration.textDirection;
     final Rect indicator = _indicatorRectFor(rect, textDirection);
     final Paint paint = Paint();
     paint.color = indicatorColor;
     paint.style = PaintingStyle.fill;
     canvas.drawRRect(
         RRect.fromRectAndRadius(indicator, Radius.circular(indicatorRadius)),
         paint);
   }
 }