Ok, with the new flutter updates I have figured out most things, but I can't seem to figure out what the elevated property wants. I have applied MaterialStateProperty.all and the property is asking for a positional argument but I don't know what it wants. I have tried double, elevatedValue and everything else predictable but I can not discern how to set this to zero. Can someone please provide a code example of the new Elevated Button with the elevation set to zero using MaterialStateProperty please?
This is how you use new Elevated button
ElevatedButtonThemeData(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
return greyColor;
}
return selectedPrimaryColor; // Defer to the widget's default.
},
),
elevation: MaterialStateProperty.resolveWith<double>( // As you said you dont need elevation. I'm returning 0 in both case
(Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
return 0;
}
return 0; // Defer to the widget's default.
},
),
foregroundColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
return greyColor;
}
return selectedPrimaryColor; // Defer to the widget's default.
},
),
),
),
Btw I extract this from themeData. So that I don't need to repeat the code again and again. You should also learn ThemeData class. Here is the docs.
Another cleaner approach from the accepted answer is to use styleFrom method:
ElevatedButton(
style: ElevatedButton.styleFrom(elevation: 0),
);
There are many ways available but this will provide more customization for the border so this is worthwhile to use this one.
style: ButtonStyle(
elevation: MaterialStateProperty.all(0),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(borderRadius: BorderRadius.zero),
),
),
Related
Hi I'm new to flutter and I want to apply disabled color and full-screen width to ElevatedButton.
So for applying color, I did like this:
ElevatedButton(
style : ButtonStyle(
backgroundColor : MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {return Colors.green;}
else {return Colors.blue;}
}
),
...
And for applying width, I did like this:
ElevatedButton(
style : ElevatedButton.styleFrom(
minimumSize : const Size.fromHeight(50)
),
...
But I have no idea how can I combine them. Please tell me.
Thanks,
You can set minimumSize in ButtonStyle too, like this:
ElevatedButton(
style: ButtonStyle(
minimumSize: MaterialStateProperty.all(Size.fromHeight(50)), /// <--- add this
backgroundColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
return Colors.green;
} else {
return Colors.blue;
}
}),
),
onPressed: (){},
child: Container(),
)
You can use merge extension
ElevatedButton(
onPressed: null,
style:
ElevatedButton.styleFrom(minimumSize: const Size.fromHeight(50))
.merge(ButtonStyle( // 👈 use merge here
backgroundColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
return Colors.green;
} else {
return Colors.blue;
}
}),
)),
child: const Text("Hello"),
),
With this approach, you'll be able to use both the minimumSize and backgroundColor properties for your ElevatedButton.
You can also use other properties that ElevatedButton.styleFrom() and ButtonStyle() have and combine them as you want.
The style property is used to customize the appearance of the button. First, it uses the ElevatedButton.styleFrom() method to create a new ButtonStyle object, and sets the minimumSize property to Size.fromHeight(40), which means that the button will have a minimum height of 40.
Then, it uses the merge() method to merge the newly created ButtonStyle object with an existing ButtonStyle object. This allows you to customize the style of the button without overwriting the existing styles.
It then uses the backgroundColor property to set the background color of the button based on its enabled/disabled state by using MaterialStateProperty.resolveWith method, which allows you to provide a callback that returns a different color based on the button's MaterialState.
This callback checks if the button is in the disabled state by checking if the MaterialState.disabled is present in the states set, if it is present it returns the color grey else it returns the color blue.
Finally, it sets the child property to a Text widget with the text "Action Title", which is displayed on the button.
The button will be rendered with a disabled state, and its background color will be grey and its minimum height will be 40, and it will display the text "Action Title"
ElevatedButton(
onPressed: (){
//action
},
style:
ElevatedButton.styleFrom(
minimumSize: const Size.fromHeight(40))
.merge(ButtonStyle( // 👈 use merge here
backgroundColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
return Colors.grey;
} else {
return Colors.blue;
}
}),
)),
child: const Text("Action Title"),
),
You can pass null to the onPressed property to see the button disable state.
ElevatedButton(
onPressed: null,
// other properties
)
After searching, I found a way to change the colors of the checkbox, but I did not find a way to change the thickness
Is there any way other than using custom checkbox
checkboxTheme: CheckboxThemeData(
checkColor: MaterialStateProperty.all(kWhiteColor),
fillColor: MaterialStateColor.resolveWith((states) {
if (states.contains(MaterialState.selected)) {
return kPrimaryColor; // the color when checkbox is selected;
}
return Colors.grey
.withOpacity(0.4); //the color when checkbox is unselected;
}),
thanks
In flutter, the checkBox widget comes with a property named side .
Using the side property, one can easily change the check box's style, color, width, etc.
Code snippet example:
Checkbox(
side: MaterialStateBorderSide.resolveWith(
(Set<MaterialState> states) {
if (states.contains(MaterialState.selected)) {
return const BorderSide(width: 3, color: Colors.red);
}
return const BorderSide(width: 2, color: Colors.green);
},
),
value: checkBoxValue,
onChanged: (bool? updatedValue) {
setState(() {
checkBoxValue = updatedValue!;
});
})
Is there a way to change the flutter MateriaButton border color (or any other properties) based on the MaterialState?
ButtonStyle(
backgroundColor: MaterialStateProperty.resolveWith<Color?>((states) => ...),
overlayColor: MaterialStateProperty.resolveWith<Color?>((states) => ...),
side: MaterialStateProperty.resolveWith<BorderSide?>((states) => {
if (states.contains(MaterialState.pressed)) {
return BorderSide(color: Colors.Blue);
}
return BorderSide(color: Colors.Red);
}),
)
Trying to set the border in this way doesn't seem to have any effect on the side, but it stays always red. Both backgroundColor and overlayColor seem to change based on the state, but the side property doesn't. Is there a way to achieve this?
Edit: Setting the side property this way seems to work after all. Also the way proposed by #nagendra nag works well too. The actual problem seems to be that the animation seems to be slow, so the change isn't visible unless the button is pressed for a short moment.
Try this
shape: MaterialStateProperty.resolveWith(
(states) {
if (states.contains(MaterialState.focused)) {
return const RoundedRectangleBorder(
side: BorderSide(color: Colors.red),
);
}
if (states.contains(MaterialState.pressed)) {
return const RoundedRectangleBorder(
side: BorderSide(color: Colors.green),
);
}
if (states.contains(MaterialState.hovered)) {
return const RoundedRectangleBorder(
side: BorderSide(color: Colors.blue),
);
}
},
),
),
I want a button that:
Changes its background color based on whether it's in the pressed, disabled or normal state
Changes its text color depending on whether it's in the disabled or normal state
I'm trying to achieve this with the ButtonStyle class.
ElevatedButton(
child: Text("Example"),
onPressed: onPressed, // onPressed is a function
style: ButtonStyle(
backgroundColor: MaterialStateProperty.resolveWith((states) {
if (states.contains(MaterialState.disabled)) { return KPColors.offWhite; }
if (states.contains(MaterialState.pressed)) { return KPColors.primaryLight; }
return KPColors.primaryExtraLight;
}),
textStyle: MaterialStateProperty.resolveWith((states) {
Color textColor = states.contains(MaterialState.disabled) ? KPColors.gray : KPColors.primary;
return TextStyle(fontSize: 18, color: textColor);
}),
overlayColor: MaterialStateProperty.all(KPColors.clear), // prevents the shimmer effect when pressing the button
shape: MaterialStateProperty.all(RoundedRectangleBorder(borderRadius: BorderRadius.circular(16))), // Rounds the corners
elevation: MaterialStateProperty.all(0), // Prevents shadow around button
),
),
The code succeeds in changing the background color of the button, but not the text color, which appears white instead of my custom color. I think this is because ElevatedButton's child is a Text widget, which has a default text color which is overriding mine.
How can I solve this? I already know that I can change the text color of the button by using ElevatedButton.styleFrom(...) and setting the onPrimary property, instead of ButtonStyle, but this would make it much more difficult to have different colors depending on the pressed and disabled states of the button.
you need to set the foregroundColor in the ButtonStyle
For example:
foregroundColor: MaterialStateProperty.resolveWith((states) {
if (states.contains(MaterialState.disabled)) { return Colors.grey; }
if (states.contains(MaterialState.pressed)) { return Colors.green; }
return Colors.blue;
})
you can use ElevatedButton.styleFrom
ElevatedButton(
child: Text("Example",style:TextStyle(color:isActive ? Colors.white : Colors.black)),
onPressed: isActive ? (){print('do somthing');} : (){}, // onPressed is a function
style: ElevatedButton.styleFrom(primary: isActive ? Colors.blue : Colors.grey),
)
import 'package:flutter/material.dart';
Widget justButton({
String btText = '',
Color bgColor = Colors.blue,
Color? txtColor = Colors.white,
Color borderColor = Colors.black,
void Function() onpressedAction,//here iam getting problem
}) {
return OutlinedButton(
//i wanted to refactor this onpressed
onPressed: () {
print('Go to events Page');
},
child: Text(btText),
style: OutlinedButton.styleFrom(
backgroundColor: bgColor,
primary: txtColor,
side: BorderSide(color: borderColor)),
);
}
This is my code here I have trying to refactor the onpressed outlinedButton ,
How can it possible to refactor a function
Did you want to fix error?
Here is my refactoring result.
import 'package:flutter/material.dart';
Widget justButton({
String btText = '',
Color bgColor = Colors.blue,
Color? txtColor = Colors.white,
Color borderColor = Colors.black,
Function? onpressedAction,//here iam getting problem
}) {
return OutlinedButton(
//i wanted to refactor this onpressed
onPressed: () => onpressedAction!(),
child: Text(btText),
style: OutlinedButton.styleFrom(
backgroundColor: bgColor,
primary: txtColor,
side: BorderSide(color: borderColor)),
);
}
The onpressed method accepts a VoidCallBack type, which is just a fancy way of saying void function(). Except, it doesn't contain any space, You can see for yourself here. So declare it like this.
Widget justButton({
....
VoidCallBack? onpressedAction,
}){
return OutlinedButton(
....
onPressed: onpressedAction,
....
}
create function like this
Widget customOutlinedButton(Function? func){
return OutlinedButton(
onPressed: func,
child: Text(btText),
style: OutlinedButton.styleFrom(
backgroundColor: bgColor,
primary: txtColor,
side: BorderSide(color: borderColor)),
);
}
now just pass the function you want to call in when onpressed
customOutlinedButton(*your function here*);