i am working on a coffee shop app in which, I have an option to toggle between three cup sizes like the attached image.
I want the selected sizes to have full opacity and other to have half opacity. the code I have written changes opacity of the selected size but when i select different size, other size opacity does not revert back to half. opacity stays full like the attached image below
class code:
enum SizeType { small, medium, large }
class CupSize extends StatefulWidget {
final String cupImage;
final SizeType size;
CupSize({
Key key,
this.cupImage,
this.size,
}) : super(key: key);
@override
_CupSizeState createState() => _CupSizeState();
}
class _CupSizeState extends State<CupSize> {
double activeSizeOpacity = 1;
double inActiveSizeOpacity = 0.5;
double activeBorderOpacity = 1;
double inActiveBorderOpacity = 0.0;
SizeType selectedSize;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
setState(() {
selectedSize = widget.size;
});
},
child: Opacity(
opacity: selectedSize == widget.size
? activeSizeOpacity
: inActiveSizeOpacity,
child: Column(
children: [
Container(
margin: EdgeInsets.symmetric(horizontal: 10, vertical: 10),
child: SvgPicture.asset(widget.cupImage),
),
Opacity(
opacity: selectedSize == widget.size
? activeBorderOpacity
: inActiveBorderOpacity,
child: Container(
color: kSecondaryColor,
height: 3,
width: 14,
),
),
],
),
),
);
}
}
class construction:
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
CupSize(
cupImage: 'assets/images/size_small.svg',
size: SizeType.small,
),
CupSize(
cupImage: 'assets/images/size_medium.svg',
size: SizeType.medium,
),
CupSize(
cupImage: 'assets/images/size_large.svg',
size: SizeType.large,
),
],
)
The problem is that you save your state of the cups inside the CupSize class and not in the stateful widget in which you construct the CupSize instances. The following code uses callback and should work:
class CupSize extends StatefulWidget {
final String cupImage;
final bool isSelected;
final Function onTapCallback; //the variables are changed
CupSize({
Key key,
this.cupImage,
this.onTapCallback,
this.isSelected,
}) : super(key: key);
@override
_CupSizeState createState() => _CupSizeState();
}
class _CupSizeState extends State<CupSize> {
double activeSizeOpacity = 1;
double inActiveSizeOpacity = 0.5;
double activeBorderOpacity = 1;
double inActiveBorderOpacity = 0.0;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: widget.onTapCallback(), //This is changed
child: Opacity(
opacity: widget.isSelected //This is changed
? activeSizeOpacity
: inActiveSizeOpacity,
child: Column(
children: [
Container(
margin: EdgeInsets.symmetric(horizontal: 10, vertical: 10),
child: SvgPicture.asset(widget.cupImage),
),
Opacity(
opacity: widget.isSelected //This is changed
? activeBorderOpacity
: inActiveBorderOpacity,
child: Container(
color: kSecondaryColor,
height: 3,
width: 14,
),
),
],
),
),
);
}
}
//Add this in the State class
SizeType selectedSize;
....
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
//initalize the CupSizes with the new variables
CupSize(
isSelected: selectedSize == SizeType.small,
cupImage: 'assets/images/size_small.svg',
onTapCallback: (){
setState((){
selectedSize = SizeType.small
});
}
),
CupSize(
isSelected: selectedSize == SizeType.medium,
cupImage: 'assets/images/size_medium.svg',
onTapCallback: (){
setState((){
selectedSize = SizeType.medium
});
}
),
CupSize(
isSelected: selectedSize == SizeType.large,
cupImage: 'assets/images/size_large.svg',
onTapCallback: (){
setState((){
selectedSize = SizeType.large
});
}
),
],
)