Issue
Basically I have two buttons widget that looks the same, the only difference is that one is with icon and the other not.
This is my widget class with icon
class ButtonElevationWithIcon extends StatelessWidget {
final String buttonText;
final Function onPressedButton;
final Icon buttonIcon;
final double height;
ButtonElevationWithIcon(
{@required this.buttonIcon,
@required this.buttonText,
this.height = 60,
@required this.onPressedButton});
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.symmetric(vertical: 5.0, horizontal: 40),
decoration: ShapeDecoration(
shape: StadiumBorder(
side: BorderSide(width: 1.0),
),
color: Colors.redAccent,
shadows: <BoxShadow>[
BoxShadow(
color: Colors.redAccent.withOpacity(0.2),
blurRadius: this.height / 5,
offset: Offset(0, this.height / 10),
),
],
),
child: TextButton.icon(
label: Center(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Stack(
children: <Widget>[
Text(
this.buttonText,
style: TextStyle(
fontFamily: 'Poppins',
fontWeight: FontWeight.bold,
fontSize: Constants.kfontSizeButton,
letterSpacing: Constants.kletterSpacing,
color: Colors.yellowAccent,
),
),
Text(
this.buttonText,
style: TextStyle(
fontFamily: 'Poppins',
fontWeight: FontWeight.bold,
fontSize: Constants.kfontSizeButton,
letterSpacing: Constants.kletterSpacing,
foreground: Paint()
..style = PaintingStyle.stroke
..strokeWidth = 1.5
..color = Colors.black,
),
),
],
),
),
),
icon: this.buttonIcon,
style: ButtonStyle(
foregroundColor: MaterialStateProperty.all<Color>(Colors.white),
backgroundColor:
MaterialStateProperty.all<Color>(Color(0xFFfa0002)),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(40.0),
))),
onPressed: onPressedButton));
}
}
And this is without it
class ButtonElevation extends StatelessWidget {
final double height;
final String buttonText;
final Function onPressedButton;
ButtonElevation(
{@required this.buttonText,
this.height = 100,
@required this.onPressedButton});
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.symmetric(vertical: 5.0, horizontal: 40),
height: this.height,
decoration: ShapeDecoration(
shape: StadiumBorder(
side: BorderSide(width: 1.0),
),
color: Colors.redAccent,
shadows: <BoxShadow>[
BoxShadow(
color: Colors.redAccent.withOpacity(0.2),
blurRadius: this.height / 5,
offset: Offset(0, this.height / 10),
),
],
),
child: TextButton(
child: Center(
child: Stack(
children: <Widget>[
Text(
this.buttonText,
style: TextStyle(
fontFamily: 'Poppins',
fontWeight: FontWeight.bold,
fontSize: Constants.kfontSizeButton,
letterSpacing: Constants.kletterSpacing,
color: Colors.yellowAccent,
),
),
Text(
this.buttonText,
style: TextStyle(
fontFamily: 'Poppins',
fontWeight: FontWeight.bold,
fontSize: Constants.kfontSizeButton,
letterSpacing: Constants.kletterSpacing,
foreground: Paint()
..style = PaintingStyle.stroke
..strokeWidth = 1.5
..color = Colors.black,
),
),
],
),
),
style: ButtonStyle(
foregroundColor: MaterialStateProperty.all<Color>(Colors.white),
backgroundColor:
MaterialStateProperty.all<Color>(Color(0xFFfa0002)),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(40.0),
))),
onPressed: onPressedButton));
}
}
I think that there should be a way in order to not repeat the code twice. I just want to change the child from TextButton.icon to TextButton.
any ideas?
Solution
You can create a single class with the icon field being optional. Then if the icon field is not null, use the TextButton.icon
else use the TextButton
.
Consider the following code
class ButtonElevationWithIcon extends StatelessWidget {
final String buttonText;
final Function onPressedButton;
final Icon buttonIcon;
final double height;
ButtonElevationWithIcon(
{this.buttonIcon,
@required this.buttonText,
this.height = 60,
@required this.onPressedButton});
Widget _label = Center(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Stack(
children: <Widget>[
Text(
this.buttonText,
style: TextStyle(
fontFamily: 'Poppins',
fontWeight: FontWeight.bold,
fontSize: Constants.kfontSizeButton,
letterSpacing: Constants.kletterSpacing,
color: Colors.yellowAccent,
),
),
Text(
this.buttonText,
style: TextStyle(
fontFamily: 'Poppins',
fontWeight: FontWeight.bold,
fontSize: Constants.kfontSizeButton,
letterSpacing: Constants.kletterSpacing,
foreground: Paint()
..style = PaintingStyle.stroke
..strokeWidth = 1.5
..color = Colors.black,
),
),
],
),
),
);
ButtonStyle = ButtonStyle(
foregroundColor: MaterialStateProperty.all<Color>(Colors.white),
backgroundColor:
MaterialStateProperty.all<Color>(Color(0xFFfa0002)),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(40.0),
),
),
);
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.symmetric(vertical: 5.0, horizontal: 40),
decoration: ShapeDecoration(
shape: StadiumBorder(
side: BorderSide(width: 1.0),
),
color: Colors.redAccent,
shadows: <BoxShadow>[
BoxShadow(
color: Colors.redAccent.withOpacity(0.2),
blurRadius: this.height / 5,
offset: Offset(0, this.height / 10),
),
],
),
child: this.buttonIcon != null ? TextButton.icon(
label: _label,
icon: this.buttonIcon,
style: _buttonStyle,
onPressed: onPressedButton,
) : TextButton(
label: _label,
style: _buttonStyle,
onPressed: onPressedButton,
),
);
}
}
We can save the label
and style
to separate variables to avoid duplication.
Check whether the icon
is null and use the TextButton.icon
or TextButton
.
Answered By – Arjunraj kokkadan
Answer Checked By – David Marino (FlutterFixes Volunteer)