Skip to content

Instantly share code, notes, and snippets.

@faustobdls
Last active December 6, 2021 19:35
Show Gist options
  • Save faustobdls/bda100d04d1ca250078ce07269b3cc03 to your computer and use it in GitHub Desktop.
Save faustobdls/bda100d04d1ca250078ce07269b3cc03 to your computer and use it in GitHub Desktop.
Animations
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
final String title;
const MyHomePage({
Key? key,
required this.title,
}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _currentPage = 0;
final PageController _pageController = PageController();
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.amber,
body: PageView(
controller: _pageController,
children: [
Scaffold(
appBar: AppBar(
title: const Text("Início"),
),
body: Container(color: Colors.red),
),
Scaffold(
appBar: AppBar(
title: const Text("Categorias"),
),
body: Container(color: Colors.blue),
),
Scaffold(
appBar: AppBar(
title: const Text("Favoritos"),
),
body: Container(color: Colors.green),
),
Scaffold(
appBar: AppBar(
title: const Text("Carrinho"),
),
body: Container(color: Colors.black),
),
Scaffold(
appBar: AppBar(
title: const Text("Perfil"),
),
body: Container(color: Colors.white),
),
],
),
bottomNavigationBar: Column(
mainAxisSize: MainAxisSize.min,
children: [
// BemolRibbon(height: 4),
SizedBox(
width: MediaQuery.of(context).size.width,
height: 4,
child: CustomPaint(
painter: BemolTabbarShape(),
child: Container(),
),
),
BottomNavigationBar(
selectedFontSize: 10.0,
unselectedFontSize: 10.0,
elevation: 0,
type: BottomNavigationBarType.fixed,
currentIndex: _currentPage,
onTap: (page) {
setState(() {
_currentPage = page;
_pageController.animateToPage(_currentPage, duration: const Duration(seconds: 1), curve: Curves.bounceInOut);
});
},
items: [
menuItem(
title: "Início",
assetIcon: Icons.home_outlined,
selectedAssetIcon: Icons.home,
),
menuItem(
title: "Categorias",
assetIcon: Icons.format_list_bulleted_outlined,
selectedAssetIcon: Icons.format_list_bulleted,
),
menuItem(
title: "Favoritos",
assetIcon: Icons.favorite_outline,
selectedAssetIcon: Icons.favorite,
),
menuItem(
title: "Carrinho",
assetIcon: Icons.shopping_cart_outlined,
selectedAssetIcon: Icons.shopping_cart,
),
menuItem(
title: "Perfil",
assetIcon: Icons.person_outline,
selectedAssetIcon: Icons.person,
),
],
),
],
),
);
}
BottomNavigationBarItem menuItem(
{String? title, IconData? assetIcon, IconData? selectedAssetIcon}) =>
BottomNavigationBarItem(
label: title,
icon: Container(
padding: const EdgeInsets.symmetric(horizontal: 6),
child: Icon(
assetIcon,
),
),
activeIcon: Container(
padding: const EdgeInsets.symmetric(horizontal: 6),
child: Icon(
selectedAssetIcon,
),
),
);
}
class BemolTabbarShape extends CustomPainter {
final double position;
final double height;
final int lineSize;
final int intermision;
BemolTabbarShape(
{this.lineSize = 10,
this.intermision = 25,
this.height = 4,
this.position = 0});
final Color ribbonBG = Colors.blue;
final Color ribbon1 = Colors.red;
final Color ribbon2 = Colors.white;
@override
void paint(Canvas canvas, Size size) {
int steps = size.width ~/ (lineSize + intermision);
Paint blueLine = Paint()
..color = ribbonBG
..strokeWidth = 1
..isAntiAlias = true;
Path bluePath = Path();
bluePath.addPolygon([
const Offset(0, 0),
Offset(size.width, 0),
Offset(size.width, height),
Offset(0, height),
], true);
Paint whiteLine = Paint()
..color = ribbon2
..strokeWidth = 1
..isAntiAlias = true;
Paint redLine = Paint()
..color = ribbon1
..strokeWidth = 1
..isAntiAlias = true;
canvas.drawPath(bluePath, blueLine);
for (var i = 0; i <= steps + 4; i++) {
var startLine = 16.0 + (i * (lineSize + intermision));
Path path = Path();
path.addPolygon([
Offset(position + startLine, 0),
Offset(position + startLine + lineSize, 0),
Offset(position + startLine + lineSize - 5, height),
Offset(position + startLine - 5, height),
], true);
if (i.isEven) {
canvas.drawPath(path, whiteLine);
} else {
canvas.drawPath(path, redLine);
}
}
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
class BemolRibbon extends StatefulWidget {
final double height;
const BemolRibbon({Key? key, this.height = 4}) : super(key: key);
@override
_BemolRibbonState createState() => _BemolRibbonState();
}
class _BemolRibbonState extends State<BemolRibbon>
with SingleTickerProviderStateMixin {
double position = -50.0;
AnimationController? controller;
Animation<double>? _animation;
@override
void initState() {
controller = AnimationController(
duration: const Duration(milliseconds: 1000), vsync: this);
controller?.forward();
controller?.addStatusListener((status) {
if (status == AnimationStatus.completed) {
controller?.reset();
} else if (status == AnimationStatus.dismissed) {
controller?.forward(from: -50.0);
}
});
_animation = Tween(begin: -50.0, end: 22.0).animate(controller!);
super.initState();
}
@override
void dispose() {
controller!.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
_animation?.addListener(() {
setState(() {
position = _animation!.value;
});
});
return SizedBox(
width: MediaQuery.of(context).size.width,
height: widget.height,
child: CustomPaint(
painter: BemolTabbarShape(height: widget.height, position: position),
child: Container(),
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment