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!
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 have a layout where I have a row and inside this row, I have a custom expansion tiles list and a custom widget, which is a rectangle with a fixed width of 5 pixels, the height of the rectangle must be the same, as the expansion tile's height.
To make the rectangle the same height as the expansion panel, I used intrinsic height.
So, the structure is this IntrinsicHeight: Row: [ExpansionPanel, Container]
The problem is that when I use IntrinsicHeight all animations are broken.
Animation in the expansion tile list is working, but the container which contains the row does not resize following the animation, but does it without any intermediate steps.
I have tried to use different types of animation.
Implicit tween animation builder
return TweenAnimationBuilder(
tween: Tween<double>(begin: 0, end: opened ? 1 : 0),
duration: Duration(milliseconds: 600),
builder: (_,double value, __){
return ClipRect(
clipBehavior: Clip.antiAlias,
child: Align(
alignment: Alignment.bottomCenter,
heightFactor: value,
child: value != 0 ? body : null,
),);
}
);
Cross fade animation
return AnimatedCrossFade(
firstChild: body,
secondChild: Container(height: 0,),
duration: Duration(milliseconds: 600),
crossFadeState: opened ? CrossFadeState.showFirst : CrossFadeState.showSecond,
sizeCurve: Curves.ease,
);
Changing animation type didn't fix my problem.
My questions are following:
Is there an option to make an animation of size simultaneously using IntrinsicHeightWidget
If there is not such an option, Is there an option to make a Rectangle widget with the same height as an expansion tile list, but without the IntrinsicHeight widget.
I have captured a video to show how the problem looks like.
https://www.youtube.com/watch?v=xpQ8QHwHUWQ
I have seen similar problems, but I didn't get success implementing them in my case.
Flutter - Animate change on height when child of container renders
Stretch children of a Flutter Row to the maximum *natural* height
How to stretch Containers inside Row to maximum available height?
Is there any way to slowly fade-in and out a floating action button? I have in my list a FAB to offer the user a way to quickly scroll to the top of the list.
So far I've found in various posts how to detect when the list is scrolled to the top or away from the top (https://medium.com/#diegoveloper/flutter-lets-know-the-scrollcontroller-and-scrollnotification-652b2685a4ac), but I fail to find how I can change the alpha value of a widget. Any idea how to solve this?
Thanks
Martin
This example is from flutter dev page:
With a AnimatedOpacity you can fade any widget.
Just put you floating action button as child of AnimatedOpacity.
Here is some example:
AnimatedOpacity(
// If the widget is visible, animate to 0.0 (invisible).
// If the widget is hidden, animate to 1.0 (fully visible).
opacity: _visible ? 1.0 : 0.0,
duration: Duration(milliseconds: 500),
// The green box must be a child of the AnimatedOpacity widget.
child: Container(
width: 200.0,
height: 200.0,
color: Colors.green,
),
);
You can find more info and full code here: https://flutter.dev/docs/cookbook/animation/opacity-animation
When the pages on page View are swiped it have have a sort of default animation that brings the page to the center of the screen.
I want the animation curve and duration of this swipe cool down and
animateTo() on button pressed to be the same.
I have tried all different curves and duration none of that matches the default.
I have also tried using Custom Scroll Physics.
In page_view.dart there's an example:
_pageController.animateToPage(
0,
duration: const Duration(milliseconds: 400),
curve: Curves.easeInOut,
);
I think it's reasonable to assume it uses 400 ms and easeInOut as default.