Reputation: 53
I'm making simple flutter app with three custom buttons, when im clicking on one button it change background color on this button. What i want to achieve is when i am clicking on button when other button is activated i want to deactivate button and activate button that i just clicked. Custom button is represented by CircleButton class and im using three of these in my main build in HomePageClass.
I wonder where it should be to turn off and turn on the appropriate buttons, it seems to me that everything should be handled in the CircleButton class.
Circle button class:
class CircleButton extends StatefulWidget {
final VoidCallback onPressed;
final String imageData;
final String buttonName;
CircleButton({this.onPressed, this.imageData, this.buttonName});
@override
_CircleButtonState createState() => _CircleButtonState();
}
class _CircleButtonState extends State<CircleButton> {
bool _active = false;
//bool isButtonActive = false;
void handleTap() {
setState(() {
/*
if(widget.buttonName == 'Mode'){
}
if(widget.buttonName =='Sounds'){
}
if(widget.buttonName =='Volume'){
}
isButtonActive = !isButtonActive;
*/
_active = !_active;
widget.onPressed();
});
//print('widget.isActive:' + isButtonActive.toString());
}
@override
Widget build(BuildContext context) {
double circleBoxSize = 50.0;
return new Column(
children: <Widget>[
FlatButton(
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
onPressed: handleTap,
child: new Container(
width: circleBoxSize,
height: circleBoxSize,
decoration: new BoxDecoration(
gradient: _active
? LinearGradient(
begin: Alignment.bottomLeft,
end: Alignment.topRight,
colors: [
Color.fromRGBO(79, 172, 254, 1),
Color.fromRGBO(0, 242, 245, 1)
])
: null,
shape: BoxShape.circle,
color: _active ? null : Color.fromRGBO(227, 230, 238, 1)),
child: new Image.asset(
this.widget.imageData,
color: _active ? Color.fromRGBO(255, 255, 255, 1) : null,
scale: 1.8,
),
),
),
SizedBox(height: 14),
new Text(
this.widget.buttonName,
style: TextStyle(
fontFamily: "Roboto",
fontSize: 14,
color: Color.fromRGBO(140, 151, 173, 1),
fontWeight: FontWeight.normal),
)
],
);
}
}
HomePage where i'm using CircleButton objects:
class _HomePageState extends State<HomePage> {
bool _active = false;
int iter = 0;
String activeButton;
List<String> selectBarData = ['dasdasdas'];
List<String> modes = ['deep-sleep', 'pain-relief'];
List<String> sounds = ['campfire', 'rain'];
void handleButtonsPress(){
setState(){
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Column(
children: <Widget>[
Container(
padding: EdgeInsets.only(left: 25, right: 25, top: 60),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <CircleButton>[
new CircleButton(
onPressed: handleButtonsPress,
imageData: 'assets/body-organ.png',
buttonName: 'Mode',
),
new CircleButton(
onPressed: handleButtonsPress,
imageData: 'assets/audio.png',
buttonName: 'Sounds',
),
new CircleButton(
onPressed: handleButtonsPress,
imageData: 'assets/speaker.png',
buttonName: 'Volume',
)
],
)),
selectBar()
],
)),
);
}
}
when im starting app and im clicking first button it looks like that:
when im clicking second button it looks like that:
but i want result like that:
Upvotes: 1
Views: 4642
Reputation: 837
I didn't have an opportunity to test this but it should work. I created a ValueChange
callback that returns the assigned tag of the button to the parent. This allows you to change the state (active or not) of the button based on whether the _active
is equivalent to the tag of the button. Hopefully, this makes sense. Here is the code, there are comments in some of the parts I changed. If you have any questions or problems let me know!
Home:
class _HomePageState extends State<HomePage> {
String _active;
int iter = 0;
String activeButton;
List<String> selectBarData = ['dasdasdas'];
List<String> modes = ['deep-sleep', 'pain-relief'];
List<String> sounds = ['campfire', 'rain'];
// ValueChanged<String> callback
void active(String btn) {
setState(() => _active = btn);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Column(
children: <Widget>[
Container(
padding: EdgeInsets.only(left: 25, right: 25, top: 60),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <CircleButton>[
new CircleButton(
action: active, //pass data from child to parent
tag: "button1", //specifies attribute of button
active: _active == "button1" ? true : false, //set button active based on value in this parent
imageData: 'assets/body-organ.png',
buttonName: 'Mode',
),
new CircleButton(
action: active,
tag: "button2",
active: _active == "button2" ? true : false,
imageData: 'assets/audio.png',
buttonName: 'Sounds',
),
new CircleButton(
action: active,
tag: "button3",
active: _active == "button2" ? true : false,
imageData: 'assets/speaker.png',
buttonName: 'Volume',
)
],
)),
selectBar()
],
)),
);
}
}
Button:
class CircleButton extends StatefulWidget {
final ValueChanged<String> action; //callback value change
final String tag; //tag of button
final String imageData;
final String buttonName;
final bool active; // state of button
CircleButton({this.action, this.imageData, this.buttonName, this.active, this.tag});
@override
_CircleButtonState createState() => _CircleButtonState();
}
class _CircleButtonState extends State<CircleButton> {
void handleTap() {
setState(() {
widget.action(widget.tag);
});
}
@override
Widget build(BuildContext context) {
double circleBoxSize = 50.0;
return new Column(
children: <Widget>[
FlatButton(
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
onPressed: handleTap,
child: new Container(
width: circleBoxSize,
height: circleBoxSize,
decoration: new BoxDecoration(
gradient: widget.active
? LinearGradient(
begin: Alignment.bottomLeft,
end: Alignment.topRight,
colors: [
Color.fromRGBO(79, 172, 254, 1),
Color.fromRGBO(0, 242, 245, 1)
])
: null,
shape: BoxShape.circle,
color: widget.active ? null : Color.fromRGBO(227, 230, 238, 1)),
child: new Image.asset(
this.widget.imageData,
color: widget.active ? Color.fromRGBO(255, 255, 255, 1) : null,
scale: 1.8,
),
),
),
SizedBox(height: 14),
new Text(
this.widget.buttonName,
style: TextStyle(
fontFamily: "Roboto",
fontSize: 14,
color: Color.fromRGBO(140, 151, 173, 1),
fontWeight: FontWeight.normal),
)
],
);
}
}
Hopefully, this is helpful!
Upvotes: 1