Skip to content

Instantly share code, notes, and snippets.

@yrom

yrom/main.dart Secret

Created November 16, 2020 13:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yrom/2f97aacf82feeb0d600c73ff47648dda to your computer and use it in GitHub Desktop.
Save yrom/2f97aacf82feeb0d600c73ff47648dda to your computer and use it in GitHub Desktop.
optimize animation in flutter
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext _) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
// This makes the visual density adapt to the platform that you run
// the app on. For desktop platforms, the controls will be smaller and
// closer together (more dense) than on mobile platforms.
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: Builder(
builder: (context) => Scaffold(
appBar: AppBar(title: Text('Bubble Animation')),
body: ListView.custom(
childrenDelegate: SliverChildListDelegate.fixed(<Widget>[
ListTile(
leading: Text('1.'),
title: Text('Use AnimationController directly'),
onTap: () {
return Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return Scaffold(
appBar: AppBar(title: Text('AnimationController')),
body: Center(
child: BubbleAnimationByAnimationController()),
);
}),
);
},
),
ListTile(
leading: Text('2.'),
title: Text('Use AnimatedBuilder'),
onTap: () {
return Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return Scaffold(
appBar: AppBar(title: Text('AnimatedBuilder')),
body: Center(child: BubbleAnimationByAnimatedBuilder()),
);
}),
);
},
),
ListTile(
leading: Text('3.'),
title: Text('Use CustomPaint'),
onTap: () {
return Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return Scaffold(
appBar: AppBar(title: Text('CustomPaint')),
body: Center(child: BubbleAnimationByCustomPaint()),
);
}),
);
},
),
]),
),
),
),
);
}
}
const double size = 80;
Widget get tips => Container(
alignment: Alignment.center,
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.blue,
),
width: size,
height: size,
child: Text(
'Hello world!',
style: TextStyle(color: Colors.white, fontSize: 12),
),
);
class BubbleAnimationByAnimationController extends StatefulWidget {
@override
_BubbleAnimationByAnimationControllerState createState() =>
_BubbleAnimationByAnimationControllerState();
}
class _BubbleAnimationByAnimationControllerState
extends State<BubbleAnimationByAnimationController>
with SingleTickerProviderStateMixin {
AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 1),
vsync: this,
)..addListener(() => setState(() {}));
_controller.repeat(reverse: true);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
alignment: Alignment.center,
constraints: BoxConstraints.tight(
Size.square((1 + _controller.value * 0.2) * size),
),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.blue[200],
),
child: tips,
);
}
}
class BubbleAnimationByAnimatedBuilder extends StatefulWidget {
@override
_BubbleAnimationByAnimatedBuilderState createState() =>
_BubbleAnimationByAnimatedBuilderState();
}
class _BubbleAnimationByAnimatedBuilderState
extends State<BubbleAnimationByAnimatedBuilder>
with SingleTickerProviderStateMixin {
AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 1),
vsync: this,
);
_controller.repeat(reverse: true);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _controller,
builder: (context, child) {
return Container(
alignment: Alignment.center,
constraints: BoxConstraints.tight(
Size.square((1 + _controller.value * 0.2) * size),
),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.blue[200],
),
child: child,
);
},
child: tips,
);
}
}
class BubbleAnimationByCustomPaint extends StatefulWidget {
@override
_BubbleAnimationByCustomPaintState createState() =>
_BubbleAnimationByCustomPaintState();
}
class _BubbleAnimationByCustomPaintState
extends State<BubbleAnimationByCustomPaint>
with SingleTickerProviderStateMixin {
AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 1),
vsync: this,
);
_controller.repeat(reverse: true);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return RepaintBoundary(
child: CustomPaint(
painter: _BubblePainter(_controller),
child: tips,
),
);
}
}
class _BubblePainter extends CustomPainter {
final Animation<double> animation;
const _BubblePainter(this.animation) : super(repaint: animation);
@override
void paint(Canvas canvas, Size size) {
final center = size.center(Offset.zero);
final radius = center.dx * (1 + animation.value * 0.2);
final paint = Paint()
..color = Colors.blue[200]
..isAntiAlias = true;
canvas.drawCircle(center, radius, paint);
}
@override
bool shouldRepaint(_BubblePainter oldDelegate) {
return oldDelegate.animation != this.animation;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment