I spent hours on implementing disabling and enabling a button (Material button, raised button, outline button and so on) below a list of Radio group with setState({}) and Shared Preference, in order to save the value of isPressed variable permanently, I even tried with FutureBuilder and Bloc…
The purpose I was trying to accomplish is the button should be disabled once it’s pressed, and enabled when new radio selection is made.
The premise of this implementation is to save the radio selection state with setState({}), you can save the selection state or value permanently by using Shared Preferences or similar methods, please see Dart Flutter: Custom Radio Button – Save Selection State with SharedPreferences-Like Methods.
Well, the radio selection state and value are all saved, now we can work on the button.
In any Flutter buttons, for example, RaisedButton, FlatButton, OutlinedButton, MaterialButton, and so on, there’s always an onPressed field, if you make this field null, the button will be disabled, and vice-versa.
So how to make it null?
In your button widget (in the class that extends StatefulWidget), create a bool value called enabled or isEnabled with final. And this bool value will receive parameter from the page that contains the button widget. Initialize the bool value with false. Code will be look like this:
class RectangleButton extends StatefulWidget {
final VoidCallback onPressedCallback;
final bool isEnabled;
RectangleButton({
...
this.isEnabled = false,
this.onPressedCallback,
...
});
@override
State<StatefulWidget> createState() {
return _RectangleButton();
}
}
Then, in your button widget state class (class extends State<[StatefulWidgetClass]>), go to onPressed field of the button widget (MaterialButton in this case), make a if statement to check if button is enabled, run method in the onPressedCallback(){}, otherwise, disable the button, the code could be like:
onPressed:widget.isEnabled ? widget.onPressedCallback : null,
And if you want to change color when the button became disabled, just add isEnabled to the disabledColor field of the MaterialButton() widget:
disabledColor: widget.isEnabled ? null : theme.disableColor,
So the code for MaterialButton will be something like this:
MaterialButton(
disabledColor: widget.isEnabled ? null : theme.disableColor,
textColor: Colors.white,
padding: EdgeInsets.all(8.spx),
child: Text(
widget.text,
style: textStyle,
),
onPressed:widget.isEnabled ? widget.onPressedCallback : null,
),
Now, let’s get to the page that implements this widget.
Create a bool value that’s called _btnEnabled, assign this local variable with false by default.
In the setState({}) that contains the radio selection state switch logic, put the _btnEnabled variable before any radio selection change, and assign true to it.
bool _btnEnabled = false;
...
onTap(){
setState(() {
_btnEnabled = true;
/* logic for saving temporary radio selection sate */
});
}
And finally, add _btnEnabled to the widget implemented in the page:
RectangleButton(
width: double.infinity,
height: 50.spx,
text: locale.login_buttonSave,
isEnabled: _btnEnabled,
onPressedCallback: _btnEnabled ? () {
//save the radio selection value and state, and refresh the page
}: null,
),