Skip to content

Instantly share code, notes, and snippets.

@densa
Created September 25, 2020 11:58
Show Gist options
  • Save densa/29208bf8e5f6546ff3c6a44f940e417a to your computer and use it in GitHub Desktop.
Save densa/29208bf8e5f6546ff3c6a44f940e417a to your computer and use it in GitHub Desktop.
import 'package:flutter/material.dart';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: TabDemo(),
),
),
);
}
}
class TabDemo extends StatefulWidget {
TabDemo({Key key}) : super(key: key);
@override
_TabDemoState createState() => _TabDemoState();
}
const BorderSide noBorder = BorderSide(width: 0.0, color: Colors.transparent);
const BorderSide activeBorder = BorderSide(width: 2.0, color: Colors.green);
class _TabDemoState extends State<TabDemo> with SingleTickerProviderStateMixin {
TabController _tabController;
int _selectedTab = 0;
@override
void initState() {
super.initState();
_tabController = TabController(vsync: this, length: tab_items.length);
_tabController.addListener((){
if (!_tabController.indexIsChanging){
setState(() {
_selectedTab = _tabController.index;
});
}
});
}
static const tab_items = [
Icon(Icons.directions_car, color: Colors.black),
Icon(Icons.directions_transit, color: Colors.black),
Icon(Icons.directions_bike, color: Colors.black),
Icon(Icons.directions_boat, color: Colors.black)
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Tab Demo"),
),
backgroundColor: Colors.white,
body: DefaultTabController(
length: tab_items.length,
child: Column(
children: <Widget>[
SizedBox(height: 5),
Container(
height: 64,
child: Stack(
overflow: Overflow.visible,
children: [
Positioned(
left: 0,
right: 0,
bottom: 0,
top: 0,
child: CustomPaint(
painter: TabbarPainter(
_selectedTab / tab_items.length, tab_items.length,
Colors.green
),
child: Container(
height: 75.0,
),
),
),
Positioned(
left: 0,
right: 0,
bottom: 0,
top: 0,
child: SizedBox(
height: 64,
width: 300,
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: tab_items.asMap().entries.map(
(item) => Expanded(
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
_tabController.index = item.key;
},
child: Container(
child: item.value,
)
),
),
).toList(),
),
),
),
],
),
),
Expanded(
child: TabBarView(
physics: NeverScrollableScrollPhysics(),
controller: _tabController,
children: tab_items,
),
),
],
)),
);
}
}
class TabbarPainter extends CustomPainter {
double loc;
int length;
Color color;
TabbarPainter(double startingLoc, int itemsLength, this.color) {
loc = startingLoc;
length = itemsLength;
}
@override
void paint(Canvas canvas, Size size) {
double radius = 10;
final paint = Paint()
..color = color
..style = PaintingStyle.stroke
..strokeWidth = 2;
final path = Path();
if (loc > 0.0) {
path.moveTo(0, size.height);
path.lineTo(loc * size.width - radius, size.height);
path.arcToPoint(
Offset((loc * size.width), size.height - radius),
radius: Radius.circular(radius),
clockwise: false
);
path.lineTo(loc * size.width, 0 + radius);
path.arcToPoint(
Offset((loc * size.width) + radius, 0),
radius: Radius.circular(radius),
);
}
if (((loc * size.width) + size.width / length) < size.width) {
path.lineTo((loc * size.width) + (size.width / length) - radius, 0);
path.arcToPoint(
Offset((loc * size.width) + size.width / length, 0 + radius),
radius: Radius.circular(radius),
);
path.lineTo((loc * size.width) + size.width / length, size.height - radius);
path.arcToPoint(
Offset((loc * size.width) + (size.width / length) + radius, size.height),
radius: Radius.circular(radius),
clockwise: false
);
path.lineTo(size.width, size.height);
} else {
path.lineTo((loc * size.width) + (size.width / length), 0);
}
canvas.drawPath(path, paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return this != oldDelegate;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment