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
)
Related
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),
)
I need to make a CupertinoDatePicker like this:
But I can't change anything except the Background.
I found an answer like this https://stackoverflow.com/a/57830696/16864379
Here's what I got:
But which parameter is responsible for the active color to make it pink?
And what parameter is responsible for removing the translucent white backing?
Thank you.
the CupertinoDatePicker's text and active text use same TextStyle,so can't just change the active color but change both.
return itemPositioningBuilder(
context,
Text(
localizations.datePickerHour(displayHour),
semanticsLabel: localizations.datePickerHourSemanticsLabel(displayHour),
style: _themeTextStyle(context, isValid: _isValidHour(selectedAmPm, index)),
),
);
TextStyle _themeTextStyle(BuildContext context, { bool isValid = true }) {
final TextStyle style = CupertinoTheme.of(context).textTheme.dateTimePickerTextStyle;
return isValid ? style : style.copyWith(color: CupertinoDynamicColor.resolve(CupertinoColors.inactiveGray, context));
}
change both color
CupertinoTheme(
data: CupertinoThemeData(
textTheme: CupertinoTextThemeData(
dateTimePickerTextStyle: TextStyle(color: Colors.pink),
),
),
child: CupertinoDatePicker(onDateTimeChanged: (_) {}),
)
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),
),
),
Hi I am still new to flutter but was trying to make a pretty simple app I thought.
This app consists of 30 buttons each in their own container. Code to follow. All I am trying to do is if a button is pressed then it will turn orange and then if it is longPressed that it goes back to its default color of white. Can someone explain how to do this. Here is an example of just 1 button.
Container(
width: 65,
height: 65,
child: MaterialButton(
shape: CircleBorder(
side: BorderSide(
width: 5,
color: Colors.blue[900],
style: BorderStyle.solid)),
child: Text(
"1",
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
color: Colors.white,
textColor: Colors.black,
onPressed: () {
setState(() {
color:
Colors.orange;
});
},
onLongPress: (){
setState(() {
color:
Colors.white;
});
},
),
),
Thanks in Advance
//declare color variable
Color myColor=Colors.white;
//set myColor to material button
color:myColor;
//in setstate use it like this
setState({
myColor=Colors.white; or myColor=Colors.orange;
})
first define a Color
Color buttonColor = Colors.white;
then pass this color to your button
MaterialButton(color: buttonColor)
after this inside your onPressed function
onPressed: () {
setState(() {
buttonColor =
Colors.orange;
});
},
I'm trying to use a bloc to check valid input and make an ElevatedButton(the new implementation for RaisedButton) either enabled or disabled. However, the enabled flag seems to not be implemented in the ElevatedButton source code despite it being shown in the docs as a constructor parameter. Was this changed and the docs not updated? I'm on flutter 1.22.4.
For context, I am using a global ElevatedButton widget for my app. Passing a null function to it caused it to cause an error. So I need the enabled flag to manually set the button enabled or not.
/// Get a custom raised button
Widget getRaisedButton(
{String buttonText,
dynamic icon,
Color buttonColor,
Color textColor,
dynamic colors,
Function onPressed,
EdgeInsetsGeometry padding,
/// A widget to be displayed instead of the button text
Widget buttonWidget,
ButtonStyle buttonStyle}) {
return ElevatedButton(
onPressed: onPressed(),
style: ButtonStyle(
visualDensity: VisualDensity.adaptivePlatformDensity,
backgroundColor: MaterialStateProperty.all<Color>(buttonColor),
padding: MaterialStateProperty.all<EdgeInsetsGeometry>(padding))
.merge(buttonStyle),
child: icon != null
? Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(padding: EdgeInsets.only(left: 8)),
icon,
Spacer(),
Text(
buttonText,
style: defaultTextStyle(
textColor != null ? textColor : colors.mainTextColor),
),
Spacer()
],
)
: buttonWidget != null
? buttonWidget
: Text(buttonText,
style: defaultTextStyle(
textColor != null ? textColor : colors.mainTextColor)),
);
}
Attempt to pass null
StreamBuilder<bool>(
stream: bloc.inputValid,
builder: (context, snapshot) {
return getRaisedButton(
colors: colors,
buttonText: continueText,
buttonColor: colors.mainButtonsColor,
textColor: colors.mainBackgroundColor,
buttonWidget: authenticationState.isAuthenticating
? CircularProgressIndicator(
backgroundColor: colors.mainBackgroundColor,
)
: null,
padding: EdgeInsets.symmetric(vertical: 12, horizontal: 100),
onPressed: !snapshot.hasData
? null
: () async {
final form = _formKey.currentState;
if (form.validate()) {
form.save();
//TODO: Use dependency injection for these
DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
AndroidDeviceInfo androidInfo =
await deviceInfo.androidInfo;
if (androidInfo.isPhysicalDevice) {
context
.read(authenticationProvider)
.setFullPhoneNumber(
"${authenticationState.phoneNumberPrefix}${_user.phoneNumber}");
context
.read(authenticationProvider)
.verifyPhoneNumber(context,
"${authenticationState.phoneNumberPrefix}${_user.phoneNumber}");
} else {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => OtpPage()));
}
}
});
}),
Noticed the elevated flag is read-only. I will pass null to the function anyway, if it causes an app breaking error I will have to use a separate Elevated button here instead of the global one then pass null to the onPressed function.