Animation, increase and decrease the size - flutter

I have a problem with the animation, I want the heart to start small, increase and then decrease in size, as shown in the gif below.
Desired animation
But the current behavior is that the heart starts out big and then slows down.
Would anyone know what it would take to fix the animation?
Here is the flutter code:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage();
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
Animation<double> _heartAnimation;
AnimationController _heartController;
#override
void dispose() {
_heartController.dispose();
super.dispose();
}
void _animate() {
_heartController
..reset()
..forward(from: 0.0)
..reverse(from: 1.0);
}
#override
void initState() {
super.initState();
final quick = const Duration(milliseconds: 500);
final scaleTween = Tween(begin: 0.0, end: 1.0);
_heartController = AnimationController(duration: quick, vsync: this);
_heartAnimation = scaleTween.animate(
CurvedAnimation(
parent: _heartController,
curve: Curves.elasticOut,
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ScaleTransition(
scale: _heartAnimation,
child: Icon(Icons.favorite, size: 160.0, color: Colors.red),
)
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_animate();
},
child: Icon(Icons.favorite_rounded),
),
);
}
}

Try this code, it works for me perfectly. If you have any questions please let know.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(home: MyHomePage());
}
}
class MyHomePage extends StatefulWidget {
MyHomePage();
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
Animation<double> animation;
AnimationController controller;
#override
void initState() {
super.initState();
final quick = const Duration(milliseconds: 500);
final scaleTween = Tween(begin: 0.0, end: 1.0);
controller = AnimationController(duration: quick, vsync: this);
animation = scaleTween.animate(
CurvedAnimation(
parent: controller,
curve: Curves.fastLinearToSlowEaseIn,
),
)..addListener(() {
setState(() => scale = animation.value);
});
}
#override
void dispose() {
controller.dispose();
super.dispose();
}
void _animate() {
animation
..addStatusListener((AnimationStatus status) {
if (scale == 1.0) {
controller.reverse();
}
});
controller.forward();
}
double scale = 0.0;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Transform.scale(
scale: scale,
child: Icon(
Icons.favorite,
size: 160.0,
color: Colors.red
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_animate();
},
child: Icon(Icons.favorite_rounded),
)
);
}
}

Related

fade slide animation flutter

I saw many webs when scroll down they have slide fade animations on their widgetI am wondering how they work! Any example with fade slide animation will be appreciated
New to flutter wondering how to do where to start
Try this code
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
/// This Widget is the main application widget.
class MyApp extends StatelessWidget {
static const String _title = 'Flutter Code Sample';
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: _title,
home: FadeTransitionExample(),
);
}
}
class FadeTransitionExample extends StatefulWidget {
#override
State<StatefulWidget> createState() => _Fade();
}
class _Fade extends State<FadeTransitionExample> with TickerProviderStateMixin {
AnimationController? animationController;
Animation<double>? _animationValue;
#override
void initState() {
super.initState();
animationController = AnimationController(vsync: this, duration: const Duration(seconds: 2),);
_animationValue = Tween<double>(begin: 0.0, end: 0.5).animate(animationController!);
animationController!.addStatusListener((status){
if(status == AnimationStatus.completed){
animationController!.reverse();
}
else if(status == AnimationStatus.dismissed){
animationController!.forward();
}
});
animationController!.forward();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Center(
child: FadeTransition(
opacity: _animationValue!,
child: Container(
color: Colors.blue,
width: 150,
height: 150,
),
),
),
),
);
}
}

How can use AnimationController in Cubit or Bloc?

I want to use AnimationController in the StatelessWidget class with Cubit or Bloc in a flutter, if anyone can help me with an example link to explain?
I think the general practice is to avoid using presentation layer components in Blocs. I would use Bloc to manage my state value, but run the animation components in a stateful widget.
Blocs
part 'side_bloc.freezed.dart';
typedef StateEmitter = Emitter<SideState>;
class SideBloc extends Bloc<SideEvent, SideState> {
SideBloc() : super(const SideState(20)) {
on<SideIncrement>(onIncrement);
on<SideDecrement>(onDecrement);
}
void onIncrement(SideIncrement event, StateEmitter emit) {
emit(state.copyWith(side: state.side + 10));
}
void onDecrement(SideDecrement event, StateEmitter emit) {
if (state.side <= 10) {
return;
}
emit(state.copyWith(side: state.side - 10));
}
}
#freezed
class SideEvent with _$SideEvent {
const factory SideEvent.increment() = SideIncrement;
const factory SideEvent.decrement() = SideDecrement;
}
#freezed
class SideState with _$SideState {
const factory SideState(int side) = _SideState;
}
Animated component
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
#override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<int> _animation;
late CurvedAnimation _curvedAnimation;
#override
void initState() {
_controller = AnimationController(
vsync: this,
duration: const Duration(seconds: 1),
);
_curvedAnimation = CurvedAnimation(
parent: _controller,
curve: Curves.elasticOut,
);
_animation = IntTween(begin: 20, end: 20).animate(_curvedAnimation);
_controller.forward();
super.initState();
}
#override
void dispose() {
_controller.dispose();
super.dispose();
}
void _animateTo(int value) {
int old = _animation.value;
_controller.reset();
_animation = IntTween(begin: old, end: value).animate(
_curvedAnimation,
);
_controller.forward();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Home'),
),
body: BlocListener<SideBloc, SideState>(
listener: (context, state) {
_animateTo(state.side);
},
child: AnimatedBuilder(
animation: _animation,
builder: (context, child) {
return SizedSquare(side: _animation.value);
},
),
),
floatingActionButton: const SideChangeButtons(),
);
}
}
class SideChangeButtons extends StatelessWidget {
const SideChangeButtons({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
onPressed: () =>
context.read<SideBloc>().add(const SideEvent.increment()),
child: const Icon(Icons.add),
),
const SizedBox(height: 8),
FloatingActionButton(
onPressed: () =>
context.read<SideBloc>().add(const SideEvent.decrement()),
child: const Icon(Icons.remove),
),
],
);
}
}
class SizedSquare extends StatelessWidget {
final int side;
const SizedSquare({
Key? key,
required this.side,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Center(
child: SizedBox.fromSize(
size: Size.square(side.toDouble()),
child: Container(color: Colors.red),
),
);
}
}
AnimationController works with TickerProviderStateMixin which means that you MUST use a statefulWidget somewhere in your widget tree.

Pass animation controller declared in the home page of the app to a button present in navigation drawer

This is the home page code:-
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
TabController _tabController;
GlobalKey<ScaffoldState> drawerKey = GlobalKey<ScaffoldState>();
AnimationController animationController;
Animation<double> animation;
bool cirAn = false;
#override
void initState() {
animationController = AnimationController(
vsync: this,
duration: Duration(milliseconds: 300),
reverseDuration: Duration(milliseconds: 300),
);
animation = CurvedAnimation(
parent: animationController,
curve: Curves.easeIn,
reverseCurve: Curves.easeOut
);
//animationController.forward();
_tabController = TabController(
initialIndex: 0,
length: 2,
vsync: this,
);
super.initState();
}
#override
void dispose() {
_tabController.dispose();
//animationController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
final themeProvider = Provider.of<DarkThemeProvider>(context);
var size = MediaQuery.of(context).size;
return cirAn
? CircularRevealAnimation(
centerOffset: Offset(size.height / 15, size.width / 3.5),
animation: animation,
child: myHomeWidget(
themeProvider,
),
)
: myHomeWidget(themeProvider);
}
i want to use the circular reveal animation for the whole app when a button in navigation drawer is clicked. In the home page there is a class called MyDrawer inside which another class named ThemeButton is there. Now when i tap on the theme button the circular reveal should happen for the whole app.
class ThemeButton
class ThemeButton extends StatefulWidget {
#override
_ThemeButtonState createState() => _ThemeButtonState();
}
class _ThemeButtonState extends State<ThemeButton>
with SingleTickerProviderStateMixin {
#override
Widget build(BuildContext context) {
final themeChange = Provider.of<DarkThemeProvider>(context);
return IconButton(
icon: Icon(
themeChange.darkTheme ? Icons.wb_sunny : Icons.brightness_3,
size: 25,
color: Colors.white,
),
onPressed: () {
themeChange.darkTheme = !themeChange.darkTheme;
},
);
}
}

Flutter collapse and expand widget with elastic animation

in this simple below ui i have Container right of screen and i want to collapse and expand it with elastic animation, for example on expand elasticIn animation and for collapse elasticOut.
Is this what you need?
import 'package:flutter/material.dart';
import 'package:flutter/physics.dart';
import 'dart:math';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: "Spring Box",
theme: ThemeData(),
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> with SingleTickerProviderStateMixin {
Animation animationIn, animationOut;
AnimationController _animationController;
#override
void initState() {
_animationController = AnimationController(
vsync: this,
value: 1.0,
duration: Duration(milliseconds: 500),
);
animationIn = CurvedAnimation(parent: _animationController, curve: Curves.elasticIn);
animationOut = CurvedAnimation(parent: _animationController, curve: Curves.elasticIn);
}
_toggleExpanded() {
if (_animationController.status == AnimationStatus.completed) {
_animationController.reverse();
} else {
_animationController.forward();
}
}
#override
Widget build(BuildContext context) {
var isExpanded = _animationController.status != AnimationStatus.completed;
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: _toggleExpanded,
child: Icon(Icons.add),
),
body: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
CollapsAnimation(
animation: isExpanded ? animationOut : animationIn,
child: Container(
color: Color(0xFF404bc4),
),
),
],
),
backgroundColor: Color(0xFFe8e8e8),
);
}
}
class CollapsAnimation extends AnimatedWidget {
CollapsAnimation({key, animation, this.child})
: super(
key: key,
listenable: animation,
);
final Widget child;
final Tween tween = Tween<double>(begin: 0, end: 80);
#override
Widget build(BuildContext context) {
Animation<double> animation = listenable;
var animationValue = tween.evaluate(animation);
double width = animationValue >= 0.0 ? animationValue : 0.0;
return Container(
width: width,
child: child,
);
}
}

How to delay list items in flutter?

I am trying to generate a list in flutter which delays every item after some delay.
I was tried using FutureBuilder and AnimatedList but i failed to get it.
import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
void main(){
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Example(),
);
}
}
class Example extends StatefulWidget {
#override
_ExampleState createState() => new _ExampleState();
}
class _ExampleState extends State<Example> with TickerProviderStateMixin{
AnimationController listViewController;
final Animation listView;
Duration duration = new Duration(seconds: 3);
Timer _timer;
#override
void initState() {
listViewController = new AnimationController(
duration: new Duration(seconds: 2),
vsync: this
);
super.initState();
}
FlutterLogoStyle _logoStyle = FlutterLogoStyle.markOnly;
item() {
_timer = new Timer(const Duration(seconds: 1), () {
return Text("cdscs");
});
}
#override
void dispose() {
listViewController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("hello"),
),
// ListView Builder
body: AnimatedList(
initialItemCount: 10,
itemBuilder: (BuildContext context,
int index,
Animation<double> animation){
return item();
},
)
);
}
}
You could use the AnimationController and an Animation for every child like this example:
class Example extends StatefulWidget {
#override
_ExampleState createState() => new _ExampleState();
}
class _ExampleState extends State<Example> with TickerProviderStateMixin {
AnimationController _animationController;
double animationDuration = 0.0;
int totalItems = 10;
#override
void initState() {
super.initState();
final int totalDuration = 4000;
_animationController = AnimationController(
vsync: this, duration: new Duration(milliseconds: totalDuration));
animationDuration = totalDuration/(100*(totalDuration/totalItems));
_animationController.forward();
}
FlutterLogoStyle _logoStyle = FlutterLogoStyle.markOnly;
#override
void dispose() {
_animationController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("hello"),
),
// ListView Builder
body: ListView.builder(
itemCount: totalItems,
itemBuilder: (BuildContext context, int index) {
return new Item(index: index, animationController: _animationController, duration: animationDuration);
},
));
}
}
class Item extends StatefulWidget {
final int index;
final AnimationController animationController;
final double duration;
Item({this.index, this.animationController, this.duration});
#override
_ItemState createState() => _ItemState();
}
class _ItemState extends State<Item> {
Animation _animation;
double start;
double end;
#override
void initState() {
super.initState();
start = (widget.duration * widget.index ).toDouble();
end = start + widget.duration;
print("START $start , end $end");
_animation = Tween<double>(
begin: 0.0,
end: 1.0,
).animate(
CurvedAnimation(
parent: widget.animationController,
curve: Interval(
start,
end,
curve: Curves.easeIn,
),
),
)..addListener((){
setState(() {
});
});
}
#override
Widget build(BuildContext context) {
return Opacity(
opacity: _animation.value,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: new Text("New Sample Item ${widget.index}"),
),
);
}
}
You can change the animation, in this case I was using opacity to simulate fade animation.
Maybe you can Check this response: https://stackoverflow.com/a/59121771/9481448
for (var i = 0; i < fetchedList.length; i++) {
future = future.then((_) {
return Future.delayed(Duration(milliseconds: 100), () {
// add/remove item
});
});