Reputation: 174
I have the following button:
class CircularButtonWithIcon extends StatefulWidget {
CircularButtonWithIcon({
Key key,
@required this.onPress,
this.padding,
this.border,
this.isMore,
this.marginRight,
this.marginLeft,
this.icon,
this.color,
this.activeColor,
this.text,
this.splashColor,
this.image,
this.hasState,
this.borderColor,
}) : super(key: key);
double padding;
double border;
double marginRight;
double marginLeft;
bool isMore = false;
Icon icon;
Image image;
Color color;
Color activeColor;
Color borderColor;
Widget text;
Color splashColor;
final Function onPress;
Function onHighlightChanged_;
bool active = false;
bool hasState;
@override
_CircularButtonWithIconState createState() => _CircularButtonWithIconState();
}
class _CircularButtonWithIconState extends State<CircularButtonWithIcon> {
@override
Widget build(BuildContext context) {
return FittedBox(
child: Container(
margin: EdgeInsets.only(
left: widget.marginLeft ?? 0, right: widget.marginRight ?? 0),
child: RawMaterialButton(
onPressed: () {
setState(() {
widget.active = !widget.active;
});
if (widget.onPress!=null)
widget.onPress();
print(widget.active);
},
fillColor: widget.active
? widget.activeColor ?? widget.color ?? Colors.transparent
: widget.color ?? Colors.transparent,
splashColor: widget.splashColor ?? Colors.grey,
child: widget.text != null
? Container(
child: widget.text,
)
: widget.image ?? widget.icon,
//padding: EdgeInsets.all(15.0),
padding: widget.padding != null
? EdgeInsets.all(widget.padding)
: EdgeInsets.all(15.0),
shape: CircleBorder(
side: BorderSide(
width: widget.border != null ? widget.border : 2.0,
style: BorderStyle.solid,
color: widget.borderColor ??
Colors.grey)),
)));
}
}
for some reason, it never changes state. It always prints true
when I press it. It should change between true
or false
. What am I doing wrong?
Also the color won't change, but this is probably because the state wont change.
I tried many things but I don't know why it happens. It's a steteful widget so its state should be possible to change.
Upvotes: 0
Views: 434
Reputation: 826
Everything in Widget
should be immutable!!! All the fields should be final
.
You should make a copy of widget.active
in _CircularButtonWithIconState
, and call setState
to change the active
in the state class.
import 'package:flutter/material.dart';
class CircularButtonWithIcon extends StatefulWidget {
CircularButtonWithIcon({
Key key,
@required this.onPress,
this.padding,
this.border,
// this.isMore,
this.active = false,
this.marginRight,
this.marginLeft,
this.icon,
this.color,
this.activeColor,
this.text,
this.splashColor,
this.image,
this.hasState,
this.borderColor,
this.onHighlightChanged_,
}) : super(key: key);
final double padding;
final double border;
final double marginRight;
final double marginLeft;
final bool isMore = false;
final Icon icon;
final Image image;
final Color color;
final Color activeColor;
final Color borderColor;
final Widget text;
final Color splashColor;
final Function onPress;
final Function onHighlightChanged_;
final bool active;
final bool hasState;
@override
_CircularButtonWithIconState createState() => _CircularButtonWithIconState();
}
class _CircularButtonWithIconState extends State<CircularButtonWithIcon> {
bool active;
@override
void initState() {
super.initState();
active = widget.active;
}
@override
Widget build(BuildContext context) {
return FittedBox(
child: Container(
margin: EdgeInsets.only(left: widget.marginLeft ?? 0, right: widget.marginRight ?? 0),
child: RawMaterialButton(
onPressed: () {
setState(() {
active = !active; // don't use widget.active
});
if (widget.onPress != null) widget.onPress();
print(active); // don't use widget.active
},
fillColor: active // don't use widget.active
? widget.activeColor ?? widget.color ?? Colors.transparent
: widget.color ?? Colors.transparent,
splashColor: widget.splashColor ?? Colors.grey,
child: widget.text != null
? Container(
child: widget.text,
)
: widget.image ?? widget.icon,
//padding: EdgeInsets.all(15.0),
padding: widget.padding != null ? EdgeInsets.all(widget.padding) : EdgeInsets.all(15.0),
shape: CircleBorder(
side: BorderSide(
width: widget.border != null ? widget.border : 2.0,
style: BorderStyle.solid,
color: widget.borderColor ?? Colors.grey),
),
),
),
);
}
}
Upvotes: 1