在 flutter 中覆盖小部件更改 child 小部件
Override widget changing child widget in flutter
基本上我有两个看起来一样的按钮小部件,唯一的区别是一个有图标,另一个没有。
这是我的小部件class,带有图标
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));
}
}
这是没有它的
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));
}
}
我认为应该有一种方法可以不重复代码两次。我只想将 child 从 TextButton.icon 更改为 TextButton。
有什么想法吗?
尝试这样的事情:
class ButtonElevation extends StatelessWidget {
final bool hasIcon;
// Your other properties.
ButtonElevation({
this.hasIcon = true,
// Your other properties.
});
@override
Widget build(BuildContext context) {
final child = RestOfYourWidget();
return hasIcon ? TextButton.icon(label: child): TextButton(child: child);
}
}
您可以创建一个 class,图标字段是可选的。然后如果图标字段不为空,则使用 TextButton.icon
否则使用 TextButton
.
考虑以下代码
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,
),
);
}
}
我们可以把label
和style
分开保存变量,避免重复。
检查 icon
是否为 null 并使用 TextButton.icon
或 TextButton
.
基本上我有两个看起来一样的按钮小部件,唯一的区别是一个有图标,另一个没有。
这是我的小部件class,带有图标
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));
}
}
这是没有它的
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));
}
}
我认为应该有一种方法可以不重复代码两次。我只想将 child 从 TextButton.icon 更改为 TextButton。
有什么想法吗?
尝试这样的事情:
class ButtonElevation extends StatelessWidget {
final bool hasIcon;
// Your other properties.
ButtonElevation({
this.hasIcon = true,
// Your other properties.
});
@override
Widget build(BuildContext context) {
final child = RestOfYourWidget();
return hasIcon ? TextButton.icon(label: child): TextButton(child: child);
}
}
您可以创建一个 class,图标字段是可选的。然后如果图标字段不为空,则使用 TextButton.icon
否则使用 TextButton
.
考虑以下代码
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,
),
);
}
}
我们可以把label
和style
分开保存变量,避免重复。
检查 icon
是否为 null 并使用 TextButton.icon
或 TextButton
.