How to build Animated splash screen with Getx? - flutter

I am confused about this. I Don't know how to update the value to animate the image in the splash screen. With the stateful widget class we call setState(() {}); inside the listener to update the value. But, How do I achieve it with the Getx?
Animation with Stateful Widget :
animationInitilization() {
animationController =
AnimationController(vsync: this, duration: const Duration(seconds: 2));
animation =
CurvedAnimation(parent: animationController, curve: Curves.easeOut);
animation!.addListener(() {
setState(() {});
});
animationController.forward();
}
Animation with Getx:
Splash Screen :
class SplashScreen extends StatelessWidget {
const SplashScreen({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
SplashScreenViewModel splashScreenViewModel =
Get.put(SplashScreenViewModel());
return Scaffold(
body: Stack(
fit: StackFit.expand,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image.asset(
'assets/images/logo.png',
width: splashScreenViewModel.animation.value * 200,
height: splashScreenViewModel.animation.value * 200,
),
],
),
],
),
);
}
}
Getx Controller :
class SplashScreenViewModel extends GetxController
with GetSingleTickerProviderStateMixin {
late AnimationController animationController;
late Animation<double> animation;
#override
void onInit() {
animationInitilization();
super.onInit();
}
animationInitilization() {
animationController =
AnimationController(vsync: this, duration: const Duration(seconds: 2));
animation =
CurvedAnimation(parent: animationController, curve: Curves.easeOut)
.obs
.value;
animation.addListener(() => update());
animationController.forward();
}
}

Nice animation for SplashScreen bro.
I recommend using GetBuilder() to make it work properly:
class SplashScreen extends StatelessWidget {
const SplashScreen({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: GetBuilder<SplashScreenViewModel>(
init: SplashScreenViewModel(),
builder: (controller) {
return Stack(
fit: StackFit.expand,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image.asset(
'assets/images/logo.png',
width: controller.animation.value * 200,
height: controller.animation.value * 200,
),
],
),
],
);
},
),
);
}
}

Related

Change scrollView offset without callback listener

I want to change scrollView's offset with code so I use ScrollController:
ScrollController _controller;
_controller.addListener(() {
print('call listener');
});
My way to change offset:
_controller.jumpTo(200);
it will callback listener once.
or
_controller.animateTo(200, duration: Duration(milliseconds: 1), curve: Curves.linear);
it will callback listener, too.
I wonder is there any way to change scrollView offset without callback listener.
Here is all my code and you can coppy and test:
import 'package:flutter/material.dart';
class SingleChildScrollViewDemoPage extends StatefulWidget {
SingleChildScrollViewDemoPage({Key key}) : super(key: key);
#override
_SingleChildScrollViewDemoPageState createState() =>
_SingleChildScrollViewDemoPageState();
}
class _SingleChildScrollViewDemoPageState
extends State<SingleChildScrollViewDemoPage> {
ScrollController _controller;
#override
void initState() {
super.initState();
_controller = ScrollController();
_controller.addListener(() {
print('call listener');
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('SingleChildScrollView')),
body: SingleChildScrollView(
controller: _controller,
child: Column(
children: [
RaisedButton(
child: Text('change offset'),
onPressed: () {
//_controller.jumpTo(200);
_controller.animateTo(200,
duration: Duration(milliseconds: 1), curve: Curves.linear);
},
),
Container(
width: 375,
height: 200,
color: Colors.red,
),
SizedBox(height: 30),
Container(
width: 375,
height: 3000,
color: Colors.green,
),
],
),
),
);
}
}

Flutter Web Mouse Region Widget Triggering

I am trying to get this result with Flutter;
I am having this behaviour;
Code;
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'dart:html' as html;
class OverlayAnimatedGridElement extends StatefulWidget {
OverlayAnimatedGridElement(this.imagepath, this.postDetail, this.postTitle);
final String imagepath;
final String postTitle;
final String postDetail;
#override
_OverlayAnimatedGridElementState createState() =>
_OverlayAnimatedGridElementState();
}
class _OverlayAnimatedGridElementState extends State<OverlayAnimatedGridElement>
with TickerProviderStateMixin {
AnimationController _controller;
Animation<double> _opacityTween;
bool isHovered = false;
#override
void initState() {
_controller =
AnimationController(vsync: this, duration: Duration(milliseconds: 500));
_opacityTween = Tween<double>(begin: 0, end: 1).animate(
CurvedAnimation(parent: _controller, curve: Curves.easeInOutCirc));
super.initState();
}
hoverActivation(hoverState) {
bool hoverState;
isHovered = hoverState;
if (isHovered = true) {
_controller.forward();
} else if (isHovered = false) {
_controller.reset();
}
print("activated");
}
#override
Widget build(BuildContext context) {
_opacityTween.addListener(() {
setState(() {
print(_opacityTween.value);
});
});
return MouseRegion(
onHover: hoverActivation(true),
child: Container(
constraints: BoxConstraints(maxHeight: 360, maxWidth: 640),
child: Stack(
alignment: Alignment.bottomCenter,
children: [
Image(image: AssetImage("${widget.imagepath}")),
Opacity(
opacity: _opacityTween.value,
child: Container(
color: Color.fromRGBO(128, 128, 128, 0.5),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
Column(
mainAxisSize: MainAxisSize.min,
children: [
Text("${widget.postDetail}"),
Text("${widget.postTitle}")
],
),
],
),
),
),
],
),
),
);
}
}
A standalone widget works okay but when I put it into gridview or pageview it automatically reads it mouse entered when I scroll into it.
I tried to use other widgets like Inkwell, Listener and others. No solution. Can someone guide me if there is better solution?
How Can I solve this?
edit:
Now having this problem. MouseRegion causes multiple controller.forwards
I am Created an Example ... please Try this,
import 'package:flutter/material.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Todos',
theme: new ThemeData(primarySwatch: Colors.deepOrange),
home: MyHome(),
);
}
}
class MyHome extends StatelessWidget{
#override
Widget build(BuildContext context) {
return GridView.count(crossAxisCount: 3,
children: List.generate(10, (index) {
return OverlayAnimatedGridElement("https://picsum.photos/300/200");
}
));
}
}
class OverlayAnimatedGridElement extends StatefulWidget {
OverlayAnimatedGridElement(this.imagepath);
final String imagepath;
// final String postTitle;
// final String postDetail;
#override
_OverlayAnimatedGridElementState createState() =>
_OverlayAnimatedGridElementState();
}
class _OverlayAnimatedGridElementState extends State<OverlayAnimatedGridElement>
with TickerProviderStateMixin {
bool isHovered = false;
#override
void initState() {
super.initState();
}
hoverActivation(hoverState) {
setState(() {
isHovered = hoverState;
});
print("activated" + hoverState.toString());
}
#override
Widget build(BuildContext context) {
return Center(
child: Container(
color: Colors.red,
height: 200,
width: 300,
child: Stack(
children: [
Image.network(widget.imagepath),
MouseRegion(
onEnter: (event){
hoverActivation(true);
},
onExit: (event){
hoverActivation(false);
},
child: AnimatedContainer(
duration: Duration(milliseconds: 200),
color: Colors.black.withOpacity(isHovered ? 0.5 : 0),
),
)
],
),
),
);
}
}
I solved my second problem by just moving addListener method to initState. Previously it was inside widget itself which was causing adding listeners in every rebuild and causing multiple rebuilds for each listener, I guess.

animate widgets based on condition in scaffold body

I have a widget, with a scaffold. His body is x widget, how do I animate in the y widget on the body instead of the x widget?
The widgets are like:
Scaffold(
body: condition ? X() : Y(),
)
When the condition goes from true to false or false to true, I want the Y or X widget to animate in. How can I do this?
You can change the Offset values to get your desired result
class Test extends StatefulWidget {
#override
_TestState createState() => _TestState();
}
class _TestState extends State<Test>
with SingleTickerProviderStateMixin {
bool condition;
AnimationController _controller;
Animation<Offset> _offsetAnimation;
#override
void initState() {
condition = false;
_controller = AnimationController(
duration: const Duration(seconds: 1),
vsync: this,
);
_offsetAnimation =
Tween<Offset>(begin: Offset(0.0, -5.0), end: Offset.zero)
.animate(CurvedAnimation(
curve: Curves.linear,
parent: _controller,
));
super.initState();
}
#override
void dispose() {
_controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: InkWell(
onTap: () {
setState(() {
condition = true;
});
_controller.forward();
},
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
color: Colors.red,
width: 200,
height: 200,
),
if (condition)
SlideTransition(
position: _offsetAnimation,
child: Container(
color: Colors.green,
width: 100,
height: 100,
),
),
],
),
),
),
);
}
}

Heigh Change Tween Animation Issue in Flutter

I want to animate the Height of My container
What I am try to do is :
class _AddVehicleState extends State<AddVehicle>
with SingleTickerProviderStateMixin {
AnimationController _otherFieldsAnimationController;
Animation<double> _heightAnimation;
override
void initState() {
_otherFieldsAnimationController = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 3000),
);
_heightAnimation = new Tween<double>(begin: 400.0, end: 20.0)
.animate(_otherFieldsAnimationController);
_otherFieldsAnimationController.forward();
}
#override
Widget build(BuildContext context) {
return new WillPopScope(
onWillPop: _onWillPop,
child: new Scaffold(body: Builder(builder: (scaffoldContext1) {
scaffoldContext = scaffoldContext1;
return Stack(
children: <Widget>[
new Container(
decoration: getGradientBackground(),
child: ListView(
children: <Widget>[
Container(
color: Colors.white70,
height: _heightAnimation.value,
child: Center(
child: Text('HEY'),
));
.
.
.
.
.
As you can see the container contains the height of Animation.
All the other animation on this page works perfectly but this container is not being animated.
Any particular reason? Or am I missing something?
You can use the animated container like this
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
AnimationController _controller;
Animation<double> _animation;
var _duration = const Duration(milliseconds: 3000);
#override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: _duration,
)..addListener(() {
setState(() {});
});
_animation =
new Tween<double>(begin: 20.0, end: 400.0).animate(_controller);
_controller.forward();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Stackoverflow'),
),
body: Center(
child: AnimatedContainer(
duration: _duration,
height: _animation.value,
width: 200,
color: Colors.amber,
),
));
}
}

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,
),
);
}
}