Why is ButtonStyle animation slowly? - flutter

I have outlined buttons with buttonstyle animation, but this animation is slowl or none because I need tap on button few milliseconds (cca 0.5s)
OutlinedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const Rekon()),
);
},
style: buttonStyle,
child: Text(
"TEXT",
style: GoogleFonts.lilitaOne(
fontSize: textSizeCalculator
.calculateTextSize(context),
),
),
),
),
ButtonStyle
ButtonStyle buttonStyle = ButtonStyle(
foregroundColor:
MaterialStateProperty.resolveWith<Color>((Set<MaterialState> states) {
if (states.contains(MaterialState.pressed)) {
return const Color.fromARGB(255, 251, 255, 0);
}
return Colors.white;
}),
overlayColor:
MaterialStateColor.resolveWith((states) => const Color(0xFF011230)),
minimumSize: const MaterialStatePropertyAll(Size.fromHeight(60)),
padding: const MaterialStatePropertyAll(EdgeInsets.all(5)),
shape: MaterialStateProperty.all<OutlinedBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0),
),
),
side: MaterialStateProperty.resolveWith<BorderSide>(
(Set<MaterialState> states) {
final Color color = states.contains(MaterialState.pressed)
? const Color.fromARGB(255, 255, 0, 0)
: Colors.lightBlueAccent;
return BorderSide(color: color, width: 2.5);
}),
);
but this animation is slow. I have to tap the button for a few milliseconds for the animation to show. How to fix it, or what to use for the requested animation?
Thank you very much in advance for the information.

Related

How to animate background color on ElevatedButton?

I would like to create a fade between two background colors when my ElevatedButton change his state to disable, how can I do that ?
final _buttonStyle = ElevatedButton.styleFrom(
backgroundColor: Colors.white,
disabledBackgroundColor: Colors.white.withOpacity(0.5),
animationDuration: const Duration(milliseconds: 0),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
);
I see there is an animationDuration property, however it seems to only create a delay between the change of color. No animations are visible.
You can use AnimatedSwitcher . First define this out of build method:
bool isVisible = false;
then do this:
AnimatedSwitcher(
child: SizedBox(
width: 100,
key: UniqueKey(),
child: ElevatedButton(
onPressed: () {
setState(() {
isVisible = !isVisible;
});
},
child: Text('click'),
style: ButtonStyle(
splashFactory: InkRipple.splashFactory,
overlayColor: MaterialStateProperty.resolveWith(
(states) {
return states.contains(MaterialState.pressed)
? Colors.grey
: null;
},
),
backgroundColor: MaterialStateProperty.all(
isVisible ? Colors.red : Colors.green)),
),
),
duration: Duration(milliseconds: 500),
),
One way you can achieve similar behavior without ElevatedButton is like so, by using AnimatedContainer and InkWell
//define a state variable
bool disableButton = false;
//build the button like so
InkWell(
onTap: disableButton ? null : () => print('Button tapped'),
child: AnimatedContainer(
duration: const Duration(milliseconds: 600),
decoration: BoxDecoration(
color: disableButton ? Colors.grey : Colors.blue,
borderRadius: BorderRadius.circular(10),
),
padding: const EdgeInsets.symmetric(horizontal: 30, vertical: 6),
child: Text('Abc'),
),
)
//make disableButton true to disable the button
setState(() => disableButton = true);

How to give Rounded Border to Elevated Button in flutter?

As RaisedButton and OutlineButton are deprecated, the flutter team introduces a new ElevatedButton. But I don't know how to make ElevatedButton's border rounded like the below image.
ElevatedButton(
onPressed: () {},
child: Text('Testing'),
),
You could do something like this:
ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0),
),
),
child: Text(' Elevated Button')
)
ElevatedButton(
style: ButtonStyle(
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
side: BorderSide(color: Colors.green)),
),
),
onPressed: () {},
child: Text('test'),
)
This is how you can use new Ele Button
ElevatedButtonThemeData(
style: ButtonStyle(
shape: MaterialStateProperty.resolveWith<OutlinedBorder>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
return ContinuousRectangleBorder(borderRadius: BorderRadius.circular(10));
}
return ContinuousRectangleBorder(borderRadius: BorderRadius.circular(10)); //CHoose any shape you want
},
),
backgroundColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
return greyColor;
}
return selectedPrimaryColor;
},
),
foregroundColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
return Colors.black;
}
return selectedPrimaryColor;
},
),
),
),

TextButton's text color not changing

I added this theme for my TextButton.
textButtonTheme: TextButtonThemeData(
style: ButtonStyle(
shape: MaterialStateProperty.all(RoundedRectangleBorder(borderRadius: BorderRadius.circular(30.0))),
textStyle: MaterialStateProperty.resolveWith(
(Set<MaterialState> states) {
if (states.contains(MaterialState.pressed) || states.contains(MaterialState.hovered))
return TextStyles.headline3.copyWith(
color: AppColors.dustyOrange,
);
return TextStyles.headline3;
},
),
side: MaterialStateProperty.resolveWith(
(Set<MaterialState> states) {
if (states.contains(MaterialState.pressed) || states.contains(MaterialState.hovered))
return BorderSide(
width: 1,
color: AppColors.dustyOrange,
);
return BorderSide(width: 1, color: AppColors.white.withOpacity(0.2));
},
),
),
)
and here is my TextButton:
TextButton(
onPressed: () => widget.onTap(),
child: Text(widget.title, style: theme?.textTheme.headline3),
style: theme?.textButtonTheme.style!.copyWith(
padding: MaterialStateProperty.all(EdgeInsets.symmetric(vertical: 15, horizontal: 20)),
)
)
The problem is that when the button pressed, the style of the button is changing, but the color is not.
There are generally three issue in your code. First, you don't need to assign style to the Text because TextButton itself has a style property. Second, you need to create a copy of TextStyle before you return it. And last, the color property needs to be changed to the foreground because the later gets precedence when there's a conflict between color and foreground.
Here's the minimal reproducible code:
#override
Widget build(BuildContext context) {
return Material(
body: Center(
child: Theme(
data: Theme.of(context).copyWith(
textButtonTheme: TextButtonThemeData(
style: ButtonStyle(
shape: MaterialStateProperty.all(RoundedRectangleBorder(borderRadius: BorderRadius.circular(30.0))),
textStyle: MaterialStateProperty.resolveWith(
(Set<MaterialState> states) {
final headline3 = Theme.of(context).textTheme.headline3;
if (states.contains(MaterialState.pressed) || states.contains(MaterialState.hovered)) {
final textStyle = headline3.copyWith(foreground: Paint()..color = Colors.orange);
return textStyle;
}
return headline3;
},
),
),
),
),
child: TextButton(
onPressed: () {},
style: Theme.of(context).textButtonTheme.style,
child: Text('Button'),
),
),
),
);
}
Output of it

Elevated Button height not increasing

Since Raised button is deprecated I replaced with Elevated Button. But I can't increase Elevated button's height.
class ZuzuButton extends StatelessWidget {
final Function onTapped;
final String name;
final double height;
final TextStyle textStyle;
final double radius;
final List<BoxShadow> shadow;
final Color color;
final bool enable;
ZuzuButton({this.onTapped,#required this.name,
this.height,this.textStyle,this.radius,this.shadow,this.color,this.enable=true});
#override
Widget build(BuildContext context) {
return Container(
height: height==0?48.0:height,
decoration: new BoxDecoration(
borderRadius: BorderRadius.circular(radius!=null?radius:30.0),
border: enable? Border.all(
width: color!=null?0.0:1.0,
color: color!=null?color:Color(0x407F16F0),
):null,
boxShadow: enable?(shadow==null?[
BoxShadow(
color: Color(0x407F16F0),
offset: Offset(0.0, 8.0),
spreadRadius: 0,
blurRadius: 20,
),
]:shadow):null,
),
child: ElevatedButton(
child: Container(
child: Center(
child: Text(name,style: textStyle!=null?textStyle:null,),
),
height: height==0?48.0:height,
),
onPressed: enable?onTapped:null,
style: ButtonStyle(
elevation: MaterialStateProperty.resolveWith<double>(
(Set<MaterialState> states) {
return 0.0;
},
),
backgroundColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.pressed))
return Color(0xffF7E86C);
return enable?(color!=null?color:null):Color(0xffDBD9D2); // Use the component's default.
},
),
textStyle: MaterialStateProperty.resolveWith<TextStyle>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.pressed))
return ZuzuTopography.FF2_Button_Bold.copyWith(color: Colors.black);
return ZuzuTopography.FF2_Button_Bold.copyWith(color: Colors.white); // Use the component's default.
},
),
shape: MaterialStateProperty.resolveWith<OutlinedBorder>(
(Set<MaterialState> states) {
// if (states.contains(MaterialState.pressed))
// return radius!=null? RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(radius),
// ):null;
return RoundedRectangleBorder(
borderRadius: BorderRadius.circular(radius!=null?radius:30.0),
); // Use the component's default.
},
),
),
),
);
}
}
My output.
How to make this button occupy its container height? I searched internet for solutions but could not found any solutions. Any suggestions in my code? Is there any alternative for Raised Button other than Elevated Button.
I just started using Elevated Button. For me I just change the height using this:
ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
minimumSize: Size(width, height) // put the width and height you want
),
child: Text("NEXT"),
)
You can use ConstrainedBox for doing the same. Please refer below code for the reference.
ConstrainedBox(
constraints: BoxConstraints.tightFor(width: 300, height: 200),
child: ElevatedButton(
child: Text('300 x 200'),
onPressed: () {},
),
),
Use SizeBox with width and height parameters.
SizedBox(
width: double.infinity,
height: 55.0,
child: ElevatedButton(
),
);
You can simply use fixedSize(width, height). Here is a sample
ElevatedButton(
onPressed: () {},
child: Text(
'submit',
),
style: ElevatedButton.styleFrom(
fixedSize: Size(90, 15),
primary: Colors.deepOrange,
),
)
You can use minimumSize property of an elevated button instead of SizedBox:
ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 0,
minimumSize: Size(100, 48), // Size(width, height)
backgroundColor: AppColors.primary,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8))),
child: Text("Button Text", style: textTheme.button),
onPressed: (){},
),

Passing route as argument in flutter

i'm kinda new to flutter and i'm trying to get two buttons on my page and make them send the user to different pages on my app. Right now I have this code for my buttons, but to make it work, I just change the last part of the code from SearchPage() to ScanPage() and this seems to be inefficient. Can I somehow pass in the pages as arguements for the button widgets?
// Button for scanPage
Widget _buttonScan(String text, Color splashColor, Color highlightColor,
Color fillColor, Color textColor) {
return RaisedButton(
highlightElevation: 0.0,
splashColor: splashColor,
highlightColor: highlightColor,
elevation: 0.0,
color: fillColor,
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0)),
child: Text(
text,
style: TextStyle(
fontWeight: FontWeight.bold, color: textColor, fontSize: 20),
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => ScanPage()),
);
},
);
}
// Button for searchPage
Widget _buttonSearch(String text, Color splashColor, Color highlightColor,
Color fillColor, Color textColor) {
return RaisedButton(
highlightElevation: 0.0,
splashColor: splashColor,
highlightColor: highlightColor,
elevation: 0.0,
color: fillColor,
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0)),
child: Text(
text,
style: TextStyle(
fontWeight: FontWeight.bold, color: textColor, fontSize: 20),
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SearchPage()),
);
},
);
}
You can pass a function as an argument to your widget that will take care of the navigation direction. In your case, either go to scanPage or searchPage, like this:
Widget _buttonScan(String text, Color splashColor, Color highlightColor,
Color fillColor, Color textColor, Widget Function() choosePage) {
return RaisedButton(
highlightElevation: 0.0,
splashColor: splashColor,
highlightColor: highlightColor,
elevation: 0.0,
color: fillColor,
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0)),
child: Text(
text,
style: TextStyle(
fontWeight: FontWeight.bold, color: textColor, fontSize: 20),
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => choosePage()),
);
},
);
}
And when you call it:
_buttonScan(...,() => ScanPage ()) //To go to ScanPage
_buttonScan(...,() => SearchPage()) //To go to SearchPage
To pass arguments you need to use named routes of the Navigator like this :
Navigator.pushNamed(
context,
ExtractArgumentsScreen.routeName,
arguments: ScreenArguments(
'Extract Arguments Screen',
'This message is extracted in the build method.',
),
);
See the official documentation