I would like to be able to always pop a screen from top to bottom. This is already working if I push like this:
static Route _createRouteWithBottomToTopTransition(Widget destinationPage) {
return PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => destinationPage,
transitionsBuilder: (context, animation, secondaryAnimation, child) {
var begin = Offset(0.0, 1.0);
var end = Offset.zero;
var curve = Curves.ease;
var tween =
Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
return SlideTransition(
position: animation.drive(tween),
child: child,
);
},
);
}
If I push with this Route I can simply call Navigator.pop(context) and the animation is as expected from top to bottom.
Problem: I don't always push with the customTransition. In some cases I simply push like this: Navigator.of(context).pushNamed('/page1') because for push I want the standard slide in fro the right animation. But page1 should still be pop from top to bottom. Is this possible? And if so, how? I tried searching for it but couldn't find anything.. I thought about creating a different customPushTransition but could not get a top to bottom animation...
Happy for every help! Let me know if you need more info!
Related
How to make the red color keep filling and walking from point to the same point in circle like following
let's say A is the starting point, red color keep filling and walking till it complete the circle in animation
You can use TweenAnimationBuilder and CircularProgressIndicator for achieving this.
TweenAnimationBuilder(
tween: Tween<double>(begin: 0, end: 1),
duration: const Duration(seconds: 3),
builder: (BuildContext context, double value, _) {
return CircularProgressIndicator(
value: value,
color: Colors.red,
backgroundColor: Colors.white,
);
},
),
If you need to respond to a value change, to follow some progress, then you can use AnimatedBuilder. The animation you supply to it makes sure that it will be rebuilt more frequently, just as needed.
Example:
TweenAnimationBuilder<double>(
tween: Tween(begin: 0, end: 1),
duration: Duration(seconds: 25),
builder: (context, value, _) => CircularProgressIndicator(value: value),
),
This is the simplest way by far. You create a tween animation that goes from zero to one, give it a duration and use it to build the progress indicator.
Or you can use the Syncfusion library, syncfusion_flutter_gauges: ^20.2.49, in the next link https://pub.dev/packages/syncfusion_flutter_gauges.
I have seen, a pretty radial sliders, i'm sure, that the libraries of Syncfusion are easy to learn, so, you can check and for the displacement of the bar you can use the widget AnimatedContainer(), and assign a variable for the pointer, then on SetState, set for the 100% and you have a simple animation of the gauge.
See more of radial sliders https://flutter.syncfusion.com/#/radial-slider/customization/thumb
I have a panel as a tabbar at the bottom with custom animation and with page names. I have 5 pages that can be switched with the next animation: the new page should slowly increase visibility (FadeTransition) and the old page should move right or left depending on what page should be next. If the new page is placed on the right hand of the current page then the slide animation should go left, if it's placed on the left hand then the slide animation should go right.
As far as I know, there is no possibility of using secondaryAnimation to use different animations based on the next page. Because when we create the current page, we don't know what closing animation for the current page should be applied, we can only use one behavior for all transitions.
In this case, maybe anyone has suggestions on how can I implement this behavior?
I've drawn a scheme for the easiest understanding.
I've made this behavior by using the provider.
Before calling Navigator.pushReplacementNamed, when I know what the next page should be, I've defined the necessary direction that the old page should move. Remember it in my model variable. I've taken then this value right in my custom PageRouteBuilder with help of the Provider.
class MainPageRoute extends PageRouteBuilder {
// ignore: unused_field
final Widget _page;
MainPageRoute(this._page)
: super(
pageBuilder: (context, animation, secondaryAnimation) => _page,
transitionsBuilder: (context, animation, secondaryAnimation, child) {
//here I've take necessary direction true = right, false = left
final _isAnimationDirectionRight =
context.read<ContextHandlingModel>().isAnimationDirectionRight;
const _begin = Offset.zero;
final _end = (_isAnimationDirectionRight)
? const Offset(0.1, 0.0)
: const Offset(-0.1, 0.0);
const _offsetCurve = Curves.fastOutSlowIn;
const _opacityCurve = Curves.easeIn;
final _offcetTween = Tween(begin: _begin, end: _end).chain(
CurveTween(curve: _offsetCurve),
);
final _opacityOldTween = Tween(begin: 1.0, end: 0.0)
.chain(CurveTween(curve: _opacityCurve));
final _opacityNewTween = Tween(begin: 0.0, end: 1.0)
.chain(CurveTween(curve: _opacityCurve));
return SlideTransition(
position: _offcetTween.animate(secondaryAnimation),
child: FadeTransition(
opacity: _opacityOldTween.animate(secondaryAnimation),
child: FadeTransition(
opacity: _opacityNewTween.animate(animation),
child: child,
),
),
);
},
);
}
I'm trying to create a page with a page slider carousel and a progress bar. When the carousel moves to another page I want that the progress bar updates from a value to another with an animation.
I tried LinearProgressIndicator but I don't know how to set animation from the old value to new one. This is what I have
LinearProgressIndicator(
minHeight: 2,
value: currentPageIndex/(pages.length - 1)
)
currentPageIndex is updated with setState() method externally.
Is there any way to do it?
Thanks in advance.
Whilst some of the other answers here might work, they are inefficient and hard to setup.
The recommended way is to use TweenAnimationBuilder, which you can learn more about here.
Take this code for example:
TweenAnimationBuilder<double>(
duration: const Duration(milliseconds: 250),
curve: Curves.easeInOut,
tween: Tween<double>(
begin: 0,
end: <your-current-value>,
),
builder: (context, value, _) =>
LinearProgressIndicator(value: value),
),
You can change the duration of the animation and the curve of the animation. When you update your value, the progress indicator should automatically animate between the previous value and the new value!
So, I'm trying to develop a photobook app which shows the photos in front and back, Now I used card to flip but I need a animation to make it look natural like having a curvature for the card during the flip and the flip should be like turning a stiffened page.
This is what I have tried
Widget __transitionBuilder(Widget widget, Animation<double> animation) {
final rotateAnim = Tween(begin: pi, end: 0.0).animate(animation);
return AnimatedBuilder(
animation: rotateAnim,
child: widget,
builder: (context, widget) {
final isUnder = (ValueKey(_showFrontSide) != widget.key);
var tilt = ((animation.value - 0.5).abs() - 0.5) * 0.003;
tilt *= isUnder ? -1.0 : 1.0;
final value = isUnder ? min(rotateAnim.value, pi / 2) : rotateAnim.value;
return Transform(
transform: Matrix4.rotationY(value)..setEntry(3, 0, tilt),
child: widget,
alignment: Alignment.center,
);
},
);
}
But it produces the result as follows. Here the card depth is felt but need curvature at the center is it possible to do so?
The result I need is like this image
The curvature at the center is it possible without curvature?
Navigator.push(
context,
PageRouteBuilder(
transitionsBuilder: (context, animation, secondaryAnimation, child) => FadeTransition(
opacity: animation,
child: child,
),
//...
),
);
You can see transitionsBuilder 3rd parameter takes an Animation but I don't understand its use. Can anyone explain that.
Docs aren't very clear.
All thanks to my friend #pskink
When the Navigator pushes a route on the top of its stack, the secondaryAnimation can be used to define how the route that was on the top of the stack leaves the screen. Similarly when the topmost route is popped, the secondaryAnimation can be used to define how the route below it reappears on the screen. When the Navigator pushes a new route on the top of its stack, the old topmost route's secondaryAnimation runs from 0.0 to 1.0. When the Navigator pops the topmost route, the secondaryAnimation for the route below it runs from 1.0 to 0.0.