I'm creating a custom checkbox-like widget that uses Card. I'm able to get the colors changing if the values are the same onTap. However, I want it to transition the color instead of it suddenly changing.
Here's my code:
return Card(
color: selected ? AppColors.primary : AppColors.primaryLight,
I'm relatively new to animations in Flutter, but coming from a strong Frontend/CSS understanding, the way I could achieve something like this is to add transition on a CSS property -- is there something similar to this in Flutter? If not, could someone point me in the right direction?
What I would do is instead of using the Card widget, I would use an AnimatedContainer and have the same condition as you for the color parameter. You will get a smooth transition when the selected value changes. However, you may need to also add boxShadow to have the same elevation effect as Card
AnimatedContainer(
duration: const Duration(milliseconds: 700),
curve: Curves.easeInOut,
decoration:BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.black,
blurRadius: 5,
spreadRadius: 5,
offset: Offset(0, 2),
),
],
color: selected ? AppColors.primary : AppColors.primaryLight,
),
)
One way to do this would be an AnimatedContainer
return Card(
child: AnimatedContainer(
duration: const Duration(milliseconds: 1000),
height: 200,
width: 200,
color: selected ? Colors.red : Colors.blue,
child: FooWidget(),
),
)
Related
I want my TextField widget to be elevated like Card or NavigationBar widgets. I'm using Material 3 (You).
I've tried using surface color from colors like:
Theme.of(context).colorScheme.surface
but it appears to be the same color as
Theme.of(context).colorScheme.background
You can wrap your text_form_field widget with Card widget and give it elevation as well as boxShadow. It will work for you.
Card(
child: //Your_text_form_field,
elevation: 10,
decoration: BoxDecoration(
boxShadow: [
new BoxShadow(
color: Colors.red,
blurRadius: 20.0,
),
],
),
how can we change the acceleration of the animation in duration or make some stops in it's duration?
for example scale a widget to 2x in 3 second than stop for a second than scale it for another 2x in 3 seconds.
AnimationController_anim1 = AnimationController(
vsync: this,
duration: Duration(milliseconds: 3000),
);
ScaleTransition(
scale: Tween(begin: 1.0, end: 2).animate(_anim1),
child: ClipRect(
clipBehavior: Clip.hardEdge,
child: OverflowBox(
maxHeight: 70,
maxWidth: 70,
child: Center(
child: Container(
decoration: BoxDecoration(
color: Colors.white38,
shape: BoxShape.circle,
),
),
),
),
),
)
You can use Curve class which provides a way to map the unit interval of animation to the desired unit interval that your want
for example, curves should implement a transform function whic are mapper that receives a time value in a range of 0,1 which indicates animations current time progress and you can return a value to indicate what should be the new progress of the animation for example you can say if time is greater than 0 then return time2 which speeds up your animation as 2x also note that you should are allowed to return value in the range of 0 to 1 so in this example, your should bound the time2 to be at most 1
Here is link to Curve class documentation :
https://api.flutter.dev/flutter/animation/Curve-class.html
also, there are a few ready to use curves in the Curves class that you can already use or look to the implementation of those to inspire :
https://api.flutter.dev/flutter/animation/Curves-class.html
as I searched around, I found the solution in two different ways, one is what Amir Hossein Mirzaei mentioned, which use Curve class, it is very powerful and flexible but it is a bit complicated and hard solution (beside being so powerful), but the second way is more handy which handled by TweenSequence as bellow :
1 - make an animation controller 2- make TweenSequence and add TweenSequenceItem for each step of animation 3- set it to widget
AnimationController _anim1 = AnimationController(
vsync: this,
duration: Duration(milliseconds: 8500),
//reverseDuration: Duration(milliseconds: 1000),
)..repeat(reverse: true);
Animation<double> _animation1 = TweenSequence(
<TweenSequenceItem<double>>[
TweenSequenceItem<double>(
tween: Tween<double>(begin: 1.0, end: 1.5),
weight: 23.5,
),
TweenSequenceItem<double>(
tween: ConstantTween<double>(1.5),
weight: 6.0,
),
TweenSequenceItem<double>(
tween: Tween<double>(begin: 1.5, end: 2.0),
weight: 23.5,
),
TweenSequenceItem<double>(
tween: ConstantTween<double>(2.0),
weight: 47.0,
),
],
).animate(_anim1);
ScaleTransition(
scale: _animation1,
child: ClipRect(
clipBehavior: Clip.hardEdge,
child: OverflowBox(
maxHeight: 70,
maxWidth: 70,
child: Center(
child: Container(
decoration: BoxDecoration(
color: Colors.white38,
shape: BoxShape.circle,
),
),
),
),
),
)
I am stuck on this. I am trying to learn Flutter. While I was doing my custom project I hit this wall. I know this can be solved with AppBar, maybe. I want to learn how to draw custom shadow or at least alter BoxShadow.
When I try to add a box shadow to my row which wrapped with container I get this result;
shadow
Code looks like this;
class HeaderContents extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
boxShadow: [BoxShadow(offset: Offset(0, 2), blurRadius: 5)]),
height: MediaQuery.of(context).size.height * 0.1,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
As you can guess I am just trying to get elevation result to the bottom. Thanks everyone.
Add the SpreaRadius and increase the OffsetY. Change all the value to get the desired need.
BoxDecoration(
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.blue.withOpacity(0.1),
spreadRadius: 5,
blurRadius: 20,
offset: Offset(
0, 10), // changes position of shadow
),
],
),
It seems it is just my retardness on assigning color. On main file I assigned both dark and bright colors for testing out dark/light mode functionality.
Changing this,
color: Theme.of(context).primaryColor
to this,
color: Theme.of(context).primaryColorDark
fixed the problem.
I wanna transform and pin top right my container when scroll. I show in image. How can I do this ?
first you will need to use either a state management method or the setState() method. You can do this with an if of two cases (true / false). finally have int values with a height and width that control this condition. If you want to add it in an animation, the codes below will help you.
AnimatedContainer(
width: width,
height: height.value,
decoration: BoxDecoration(
color: kAffirmativeColor,
borderRadius: BorderRadius.circular(12),
),
duration: const Duration(milliseconds: 200),
curve: Curves.fastOutSlowIn,)
I want to make the same effect as this: https://api.flutter.dev/flutter/widgets/SizeTransition-class.html but starting from the beginning of an image. I tried everything and this does not work!
I tried to put Align in it, to put a container with the width modified by the value of the animation.. nothing works!
I have an animation before, and then it will call forward() on this one when it finishes (there is a function called complete that calls the forward() function).
initState() {
_sizeController =
AnimationController(duration: Duration(seconds: 1), vsync: this)
..addListener(() {
setState(() {});
});
_sizeAnimation = Tween(begin: 0.0, end: 27.0).animate(CurvedAnimation(
parent: _sizeController, curve: Curves.fastLinearToSlowEaseIn));
}
AnimatedContainer(
width: _width,
height: _height,
duration: Duration(milliseconds: 200),
decoration: BoxDecoration(
color: _color,
border: Border.all(
color: Color(0xFF707070), width: 2, style: BorderStyle.solid),
borderRadius: BorderRadius.circular(14.0),
),
child: SizeTransition(
sizeFactor: _sizeAnimation,
axis: Axis.horizontal,
axisAlignment: -1,
child:
Center(child: Image.asset('assets/images/check.png')),
),
Or it does nothing or it animates by scaling only.. How can i achieve the same effect as the example video on the widget page? I want that effect to happen showing a checkmark image inside a circle container. And before this the animatedcontainer will be a linear container that turns into the circle, and then the checkmark appears.
you need to call _sizeController.forward() to run the animation