Flutter, How to make a container disappear after som time? - flutter

So I have written this code which lets an animation play where i pressed. So if i press the screen there is a short animation playing where i pressed, if you press multiple times there are multiple animations on the screen for a short period. Each time I press the screen there is a container taking up place where the animation is played, but this container keeps taking up space even when the animation is not playing. So if i press on the screen where there already is a container an animation won't be played.
How do I make the container disappear after some time so that I can press so many times I want on the screen and still have an animation to be played?
This is all the code responsible for that animation:
class HomePage extends StatefulWidget{
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage>
with SingleTickerProviderStateMixin {
final tappedPositions = <Offset>[];
AnimationController _animationController;
#override
void initState() {
_animationController = AnimationController(
vsync: this,
duration: const Duration(seconds: 2),
);
super.initState();
}
new GestureDetector(
onTapUp: (tabDetails) {
setState(() {
tappedPositions.add(tabDetails.localPosition);
});
},
child: Container(
color: Colors.transparent,
),
),
for (final position in tappedPositions)
Positioned(
top: position.dy,
left: position.dx,
child: MyAnimatedWidget(
animation: _animationController,
),
),
],
);
}
}
class MyAnimatedWidget extends StatelessWidget {
final Animation animation;
const MyAnimatedWidget({Key key, this.animation}) : super(key: key);
#override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: animation,
child: Container(
height: 80.0,
width: 80.0,
child: new FlareActor(
"assets/images/tryckplats.flr",
animation: "tryck",
),
),
builder: (context, child) {
return Transform(
alignment: Alignment.center,
child: child,
);
},
);
}
}

Instead of using a for loop and building a widget per offset in tappedPositions, use a function that inserts a new widget with offset into a list in state, then map the list of children in a stack. Now the tapped animation can be played over another, and you can delete by key from the list after the timer expires.
class _HomePageState extends State<HomePage>
with SingleTickerProviderStateMixin {
final _animatedBoxes = <Widget>[];
AnimationController _animationController;
#override
void initState() {
_animationController = AnimationController(
vsync: this,
duration: const Duration(seconds: 2),
);
super.initState();
}
Widget _buildAnimatedBox(Offset position) {
setState({
animatedBoxes.add(
Positioned(
key: Key(animatedBoxes.length)
top: position.dy,
left: position.dx,
child: MyAnimatedWidget(
animation: _animationController,
),
}
);
}
Widget build(BuildContext context)
return GestureDetector(
onTapUp: (tabDetails) => _buildAnimatedBox(tabDetails)
child: Stack(
children: _animatedBoxes
),
);
}
}

Related

animation with bloc package on flutter

please check my code I want to use this animation with the bloc package,
and also I want to use that without StatefulWidget class :
class LoadingScreen extends StatefulWidget {
const LoadingScreen({Key? key}) : super(key: key);
#override
State<LoadingScreen> createState() => _LoadingScreenState();
}
class _LoadingScreenState extends State<LoadingScreen>
with TickerProviderStateMixin {
late AnimationController controller;
late AnimationController controller2;
late Animation<Offset> disk;
late Animation<Offset> offset;
int diskPicW = 0;
#override
void initState() {
super.initState();
controller =
AnimationController(vsync: this, duration: Duration(seconds: 1));
controller2 = AnimationController(
vsync: this, duration: Duration(seconds: 1, milliseconds: 500));
offset = Tween<Offset>(begin: Offset(1.0, 0.0), end: Offset.zero)
.animate(controller);
disk = Tween<Offset>(begin: Offset(-1.0, 0.0), end: Offset.zero)
.animate(controller2);
controller.forward();
controller2.forward();
Timer(Duration(seconds: 2, milliseconds: 500), (() {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => FirstPage(),
));
}));
}
SizeController() {
setState(() {});
}
#override
void dispose() {
super.dispose();
controller.dispose();
controller2.dispose();
}
#override
Widget build(BuildContext context) {
print(MediaQuery.of(context).size.width);
print(MediaQuery.of(context).size.height);
return Scaffold(
backgroundColor: color3,
body: Stack(
children: [
SlideTransition(
position: offset,
child: Center(
child: Image.asset(
'assets/001.png',
width: 150,
height: 150,
),
),
),
SlideTransition(
position: disk,
child: AnimatedBuilder(
animation: controller2.view,
builder: (context, child) {
return Transform.rotate(
angle: controller2.value * 2 * pi,
child: child,
);
},
child: Center(
child: Image.asset(
'assets/disk2.png',
width: 130,
height: 130,
),
),
),
),
SlideTransition(
position: offset,
child: Center(
child: Image.asset(
'assets/002.png',
width: 150,
height: 150,
),
),
)
],
),
);
}
}
This is my simple animation code
How can I run this animation using the bloc package?
I want without using the StatefulWidget class make that
I want to use the bloc package and I don't know how
Please teach me, thank you

Start Animation With Screen Loading - Flutter

I'm making a Splash Screen in my app.
In my splash screen, I want to animate(zoom in) my logo
I want to animate my logo, as soon as the screen starts.
This is my code so far...
class SplashScreen extends StatefulWidget {
#override
_SplashScreenState createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
final _splashDelay = 2000;
double _height = 10.0;
#override
void initState() {
// TODO: implement initState
super.initState();
_loadWidget();
}
_loadWidget() async {
var _duration = Duration(milliseconds: _splashDelay);
return Timer(_duration, navigationPage);
}
void navigationPage() {
Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => LoginScreen()));
}
#override
Widget build(BuildContext context) {
FlutterStatusbarcolor.setStatusBarColor(Colors.red[900]);
FlutterStatusbarcolor.setStatusBarWhiteForeground(true);
return Scaffold(
body: Stack(
children: [
SafeArea(
child: Container(
width: double.infinity,
height: double.infinity,
margin: EdgeInsets.symmetric(
horizontal: 15,
vertical: 30,
),
child: Card(
elevation: 4.5,
child: Center(
child: AnimatedContainer(
duration: Duration(milliseconds: 2000),
height: _height,
child: Image.asset('assets/images/logo.png'),
),
),
),
),
),
],
),
);
}
}
What I want is, to change the height of the AnimatedContainer() from 10 to 100 as soon as this screen starts.
I've been trying to achieve this since 3hrs now, but couldn't help myself get through. Now I'm seeking for your help/guidance. Thank you.
You must create an AnimationController and TweenAnimation that goes from the begin (10) to the end (100).
In this case, the controller is just for (redundant, I know) control the animation and when it should start.
When you create a Tween, and apply the method animate() you're just saying that you want the animation to start at the begin of this tween and end at the end of it within the time that you specified in the controller Duration.
final _splashDelay = 2000;
Animation height;
AnimationController _controller;
#override
void initState() {
// TODO: implement initState
super.initState();
_controller=AnimationController(vsync: this, duration: Duration(milliseconds:_splashDelay,),)..forward();
_controller.addListener(
() {
setState(() {});
},
);
height=Tween<double>(begin:10, end:100,).animate(_controller);
_loadWidget();
}
Then, when you're building your AnimatedContainer, you must provide height: _height.value
Here you're just saying "Flutter, please change the value of this variable from 10 to 100 in a 2000 milliseconds interval, and use this value to draw the height of this Container"
Please note the you must add the mixin SingleTickerProviderStateMixin to your state. If you don't, vsync: this won't work.
You need a ScaleTransition widget to achieve your goal.
You can checkout the working sample of your code below:
class SplashScreen extends StatefulWidget {
#override
_SplashScreenState createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen>
with SingleTickerProviderStateMixin {
final _splashDelay = 2000;
double _height = 10.0;
AnimationController _animationController;
#override
void initState() {
// TODO: implement initState
_animationController =
AnimationController(vsync: this, duration: const Duration(seconds: 2));
_animationController.forward();
super.initState();
_loadWidget();
}
#override
void dispose() {
_animationController.dispose();
super.dispose();
}
_loadWidget() async {
var _duration = Duration(milliseconds: _splashDelay);
return Timer(_duration, navigationPage);
}
void navigationPage() {
Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => LoginScreen()));
}
#override
Widget build(BuildContext context) {
FlutterStatusbarcolor.setStatusBarColor(Colors.red[900]);
FlutterStatusbarcolor.setStatusBarWhiteForeground(true);
return Scaffold(
body: Stack(
children: [
SafeArea(
child: Container(
width: double.infinity,
height: double.infinity,
margin: EdgeInsets.symmetric(
horizontal: 15,
vertical: 30,
),
child: Card(
elevation: 4.5,
child: Center(
child: ScaleTransition(
scale: _animationController,
child: Image.asset('assets/images/logo.png'),
),
),
),
),
),
],
),
);
}
}

Flutter add animation small to big

Need to know how can i add some animation on my splash screen. I just need to add when app open the center image will show small to large.
My code
class _MyHomePageState extends State<MyHomePage> {
#override
void initState() {
super.initState();
Timer(
Duration(seconds: 3),
() => Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (BuildContext context) => HomeScreen())));
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/bg#3x.png"),
fit: BoxFit.cover,
),
),
child: Center(
child: Image.asset("assets/logo#2x.png"),
) /* add child content here */,
),
);
}
}
You can use Tween AnimationController with AnimatedBuilder to for this purpose. Here's an example you just need to replace Container with your Image or you can also wrap the Image with a Container.
Since, you want the image to increase the size at splash screen so use forward() property of AnimationController in initState.
Then replace the height and width property of your image with _animationSize.value. Adjust the size according to your need here:
Size:
_tweenSize = Tween(begin: 50, end: 200);
Duration:
_animationController = AnimationController(vsync: this, duration: Duration(milliseconds: 400));
Replace:
AnimatedBuilder(
animation: _animationSize,
builder: (context, child) {
// Put your image here and replace height, width of image with _animationSize.value
return Container(
color: Colors.red,
height: _animationSize.value,
width: _animationSize.value,
);
}),
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen>
with SingleTickerProviderStateMixin {
Tween<double> _tweenSize;
Animation<double> _animationSize;
AnimationController _animationController;
#override
void initState() {
_animationController =
AnimationController(vsync: this, duration: Duration(milliseconds: 400));
_tweenSize = Tween(begin: 50, end: 200);
_animationSize = _tweenSize.animate(_animationController);
_animationController.forward();
super.initState();
}
#override
void dispose() {
_animationController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: AnimatedBuilder(
animation: _animationSize,
builder: (context, child) {
// Put your image here and replace height, width of image with _animationSize.value
return Container(
color: Colors.red,
height: _animationSize.value,
width: _animationSize.value,
);
}),
),
);
}
}

Animate button rotation

I'm trying to animate rotation of icon inside custom button to 180 degree on each press. I'm bit confused from the flutter documentation. I know I should use RotationTransition but I just can not find out how.. Here is my button
SizedBox.fromSize(
size: Size(50, 50),
child: ClipOval(
child: Material(
color: Colors.blue,
child: InkWell(
onTap: () {},
splashColor: Colors.black12,
child: RotationTransition(. //<== that is where I get
child: Icon(
Icons.filter_list, //rotate this icon
color: Colors.white,
),
),
),
),
),
),
Basically, you need a Stateful widget with an AnimationController which creates controls the animation. It's important to create that controller on the initState() method, and dispose it on the dispose() method to prevent possible errors.
Once you have the controller, you can use a bool to store the rotation direction and an Animation controlled by the Animation controller to rotate the widget. First, it goes from 0 to 0.5, and then from 0.5 to 1.
The code can be like this. You can also take a look at this codepen I created for the example.
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: MyWidget(),
),
);
}
class MyWidget extends StatefulWidget{
#override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget>
with SingleTickerProviderStateMixin{
AnimationController _controller;
Animation<double> _animation;
bool dir = true;
#override
void initState(){
_controller = AnimationController(vsync: this, duration: Duration(seconds: 1));
super.initState();
}
#override
void dispose(){
_controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
_animation = Tween<double>(
begin: dir ? 0:0.5,
end: dir ? 0.5:1
).animate(_controller);
return Scaffold(
body: Center(
child: RotationTransition(
turns: _animation,
child: RaisedButton(
child: Text("Rotate"),
onPressed: (){
_controller.forward(
from: 0
);
setState(() {dir = !dir;});
}
)
)
),
);
}
}

How to rotate an image using Flutter AnimationController and Transform?

I have star png image and I need to rotate the star using Flutter AnimationController and Transformer. I couldn't find any documents or example for image rotation animation.
Any idea How to rotate an image using Flutter AnimationController and Transform?
UPDATE:
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
AnimationController animationController;
#override
void initState() {
super.initState();
animationController = new AnimationController(
vsync: this,
duration: new Duration(milliseconds: 5000),
);
animationController.forward();
animationController.addListener(() {
setState(() {
if (animationController.status == AnimationStatus.completed) {
animationController.repeat();
}
});
});
}
#override
Widget build(BuildContext context) {
return new Container(
alignment: Alignment.center,
color: Colors.white,
child: new AnimatedBuilder(
animation: animationController,
child: new Container(
height: 80.0,
width: 80.0,
child: new Image.asset('images/StarLogo.png'),
),
builder: (BuildContext context, Widget _widget) {
return new Transform.rotate(
angle: animationController.value,
child: _widget,
);
},
),
);
}
}
Full example (null safe):
Press "go" makes the star icon spin until you press "stop".
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 {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
#override
void initState() {
_controller = AnimationController(
duration: const Duration(milliseconds: 5000),
vsync: this,
);
super.initState();
}
#override
void dispose() {
_controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Demo"),
),
body: Center(
child: Column(
children: <Widget>[
RotationTransition(
turns: Tween(begin: 0.0, end: 1.0).animate(_controller),
child: Icon(Icons.stars),
),
ElevatedButton(
child: Text("go"),
onPressed: () => _controller.forward(),
),
ElevatedButton(
child: Text("reset"),
onPressed: () => _controller.reset(),
),
],
),
),
);
}
}
Step by step guide:
First, let your widget state class implement SingleTickerProviderStateMixin.
Secondly, define an AnimationController and don't forget to dispose it. If you are not yet using null-safe, remove the late keyword.
late AnimationController _controller;
#override
void initState() {
_controller = AnimationController(
duration: const Duration(milliseconds: 5000),
vsync: this,
);
super.initState();
}
#override
void dispose() {
_controller.dispose();
super.dispose();
}
Then wrap your Widget with RotationTransition.
RotationTransition(
turns: Tween(begin: 0.0, end: 1.0).animate(_controller),
child: Icon(Icons.stars),
),
Finally, call methods on the AnimationController to start/stop animation.
Run the animation once, use .forward
Loop the animation, use .repeat
Stop immediately, use .stop
Stop and set it back to original rotation, use .reset
Stop and animate to a rotation value, use .animateTo
Screenshot (Null Safe)
Full code:
import 'dart:math' as math;
class _FooPageState extends State<FooPage> with SingleTickerProviderStateMixin{
late final AnimationController _controller = AnimationController(vsync: this, duration: Duration(seconds: 2))..repeat();
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: AnimatedBuilder(
animation: _controller,
builder: (_, child) {
return Transform.rotate(
angle: _controller.value * 2 * math.pi,
child: child,
);
},
child: FlutterLogo(size: 200),
),
),
);
}
}
Here my example of rotating image. I don't know - but maybe it suits for you
AnimationController rotationController;
#override
void initState() {
rotationController = AnimationController(duration: const Duration(milliseconds: 500), vsync: this);
super.initState();
}
//...
RotationTransition(
turns: Tween(begin: 0.0, end: 1.0).animate(rotationController),
child: ImgButton(...)
//...
rotationController.forward(from: 0.0); // it starts the animation
UPD - how to solve problem with Transform.rotate
In your case all works exactly as you've written - it rotates image from 0.0 to 1.0 (it's default parameters for AnimationController). For full circle you have to set upper parameter to 2 * pi (from math package)
import 'dart:math';
//...
animationController = AnimationController(vsync: this, duration: Duration(seconds: 5), upperBound: pi * 2);
Here i rotate 3 images at once... images saved in assets folder... if you want you can use network images also... i am here rotate 3 images on 3 speeds...
import 'package:flutter/material.dart';
import 'package:fynd/services/auth.dart';
import 'dart:async';
import 'package:fynd/services/cons.dart';
class SplashScreen extends StatefulWidget {
_SplashScreen createState() => new _SplashScreen();
}
class _SplashScreen extends State<StatefulWidget>
with SingleTickerProviderStateMixin {
AnimationController animationController;
#override
void initState() {
super.initState();
animationController = new AnimationController(
vsync: this,
duration: new Duration(seconds: 5),
);
animationController.repeat();
}
#override
Widget build(BuildContext context) {
return new Container(
alignment: Alignment.center,
color: Colors.white,
child: new AnimatedBuilder(
animation: animationController,
child: new Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/splash_circle3.png'))),
child: new AnimatedBuilder(
animation: animationController,
child: new Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/splash_circle2.png'))),
child: new AnimatedBuilder(
animation: animationController,
child: Container(
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(
'assets/images/splash_circle1.png'))),
)),
builder: (BuildContext context, Widget _widget) {
return new Transform.rotate(
angle: animationController.value * 4,
child: _widget,
);
}),
),
builder: (BuildContext context, Widget _widget) {
return new Transform.rotate(
angle: animationController.value * 5,
child: _widget,
);
},
),
),
builder: (BuildContext context, Widget _widget) {
return new Transform.rotate(
angle: animationController.value * 6,
child: _widget,
);
},
),
);
}
}
here i put the animated builder in Stack. then you can animate image rotate right(clockwise) and rotate left(anti clockwise).
import 'package:flutter/material.dart';
import 'package:fynd/services/auth.dart';
import 'dart:async';
import 'package:fynd/services/cons.dart';
class SplashScreen extends StatefulWidget {
_SplashScreen createState() => new _SplashScreen();
}
class _SplashScreen extends State<StatefulWidget>
with SingleTickerProviderStateMixin {
AnimationController animationController;
#override
void initState() {
super.initState();
animationController = new AnimationController(
vsync: this,
duration: new Duration(seconds: 5),
);
animationController.repeat();
}
#override
Widget build(BuildContext context)
return new Container(
alignment: Alignment.center,
color: Colors.white,
child: new Stack(children: <Widget>[
new AnimatedBuilder(
animation: animationController,
child :Container(
decoration: BoxDecoration(
image: DecorationImage(image: AssetImage('assets/images/splash_circle3.png'),fit: BoxFit.cover)),
),
builder: (BuildContext context, Widget _widget) {
return new Transform.rotate(
angle: animationController.value * 10,
child: _widget,
);
},
),
new AnimatedBuilder(
animation: animationController,
child: Container(
decoration: BoxDecoration(
image: DecorationImage(image: AssetImage('assets/images/splash_circle2.png'),fit: BoxFit.cover)),
),
builder: (BuildContext context, Widget _widget) {
return new Transform.rotate(
angle: -animationController.value * 10,
child: _widget,
);
},
),
new AnimatedBuilder(
animation: animationController,
child: Container(
decoration: BoxDecoration(
image: DecorationImage(image: AssetImage('assets/images/splash_circle1.png'), fit: BoxFit.cover)),
),
builder: (BuildContext context, Widget _widget) {
return new Transform.rotate(
angle: animationController.value * 10,
child: _widget,
);
}),
],),
);
}
}
Flutter also has the widget AnimatedRotation (docs) which makes rotating something much easier.
You only need a double to set the state of the rotation. It works in a percentage of rotation, if you turn it into degrees, it will be 0.0 = 0deg, 1.0 = 360deg
double turns = 0.0;
AnimatedRotation(
duration: const Duration(milliseconds: 500),
turns: turns,
child: const Icon(Icons.refresh),
)
To make the rotation happen you only need to update the state, and Flutter will execute the animation automatically
void _changeRotation() {
setState(() => turns += 1.0 / 8.0);
}
Full example taken from the Flutter docs to rotate the flutter Logo
class LogoRotate extends StatefulWidget {
const LogoRotate({Key? key}) : super(key: key);
#override
State<LogoRotate> createState() => LogoRotateState();
}
class LogoRotateState extends State<LogoRotate> {
double turns = 0.0;
void _changeRotation() {
setState(() => turns += 1.0 / 8.0);
}
#override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: _changeRotation,
child: const Text('Rotate Logo'),
),
Padding(
padding: const EdgeInsets.all(50),
child: AnimatedRotation(
turns: turns,
duration: const Duration(seconds: 1),
child: const FlutterLogo(),
),
),
],
);
}
}
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
AnimationController animationController;
#override
void initState() {
super.initState();
animationController = new AnimationController(
vsync: this,
duration: new Duration(milliseconds: 5000),
);
animationController.repeat();
}
#override
Widget build(BuildContext context) {
return new Container(
alignment: Alignment.center,
color: Colors.white,
child: RotationTransition(
child: Icon(Icons.refresh),
turns: controller,
)
);
}
}
_controller = AnimationController(duration: const Duration(seconds: 3), vsync: this);
_animation = Tween(begin: 0.0, end: 250.0).animate(_controller)
..addListener(() {
setState(() {});
})
..addStatusListener((state) {
if (state == AnimationStatus.completed) {
print("complete");
}
});
_controller.forward();
new Future.delayed(
const Duration(seconds: 5),
() => Navigator.push(
context,
MaterialPageRoute(builder: (context) => SignScreen()),
));
full example just call
ImageAnimateRotate( your widget )
class ImageAnimateRotate extends StatefulWidget {
final Widget child;
const ImageAnimateRotate({Key? key, required this.child}) : super(key: key);
#override
_ImageAnimateRotateState createState() => _ImageAnimateRotateState();
}
class _ImageAnimateRotateState extends State<ImageAnimateRotate> with SingleTickerProviderStateMixin {
late final AnimationController _controller;
#override
void initState() {
super.initState();
_controller = AnimationController(vsync: this, duration: Duration(seconds: 20))..repeat();
}
#override
Widget build(BuildContext context) {
return Center(
child: AnimatedBuilder(
animation: _controller,
builder: (_, child) {
return Transform.rotate(
angle: _controller.value * 2 * math.pi,
child: child,
);
},
child: widget.child,
),
);
}
}