I have a widget in which I create random color
Set<Color> getColorSet({int numberOfColor = 3}) {
Set<Color> generatedColorSet = Set<Color>();
while (generatedColorSet.length != numberOfColor) {
generatedColorSet.add(
Colors.primaries[Random().nextInt(Colors.primaries.length)],
);
}
return generatedColorSet;
}
Set<Color> colorSet = Set<Color>();
@override
void initState() {
super.initState();
colorSet = getColorSet();
}
and random dimensions/coordinates for a button
@override
Widget build(BuildContext context) {
double maxWidth = MediaQuery.of(context).size.width;
double maxHeight = MediaQuery.of(context).size.height;
Random randomT = new Random();
int minT = 3;
int maxT = maxHeight.toInt() - 80;
int randomTop = minT randomT.nextInt(maxT - minT);
Random randomL = new Random();
int minL = 3;
int maxL = maxWidth.toInt() - 80;
int randomLeft = minL randomL.nextInt(maxL - minL);
Random randomH = new Random();
int minH = 70;
int maxH = maxHeight.toInt() - randomTop;
int randomHeight = minH randomH.nextInt(maxH - minH);
Random randomW = new Random();
int minW = 70;
int maxW = maxWidth.toInt() - randomLeft;
int randomWidth = minW randomW.nextInt(maxW - minW);
Random randomR = new Random();
int minR = 1;
int maxR = 75;
int randomRadius = minR randomR.nextInt(maxR - minR);
I pass these values to the button located inside the Stack
Container(
child: Positioned(
height: randomHeight.toDouble(),
width: randomWidth.toDouble(),
top: randomTop.toDouble(),
left: randomLeft.toDouble(),
child: SizedBox(
child: ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(colorSet.elementAt(0)),
overlayColor: MaterialStateProperty.all(colorSet.elementAt(1)),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(randomRadius.toDouble()),
side: BorderSide(color: colorSet.elementAt(2), width: 5),
),
),
padding: MaterialStateProperty.all(EdgeInsets.all(10)),
minimumSize: MaterialStateProperty.all(Size(70,70)),
),
onPressed: () {
setState(() {
colorSet = getColorSet();
});
},
child: const Text(
'PRESS',
style: TextStyle(color: Colors.white),
),
),
),
),
),
The problem is that if I want to add another button inside the Stack, it will get the same values as the other one and will overlap it and have the same colors. How do I pass my random values different for each button ?
Below is my widget entirely with two buttons that now have the same values
class ButtonWidget extends StatefulWidget {
const ButtonWidget({Key? key,}) : super(key: key);
@override
State<ButtonWidget> createState() => _ButtonWidgetState();
}
class _ButtonWidgetState extends State<ButtonWidget> {
Set<Color> getColorSet({int numberOfColor = 3}) {
Set<Color> generatedColorSet = Set<Color>();
while (generatedColorSet.length != numberOfColor) {
generatedColorSet.add(
Colors.primaries[Random().nextInt(Colors.primaries.length)],
);
}
return generatedColorSet;
}
Set<Color> colorSet = Set<Color>();
@override
void initState() {
super.initState();
colorSet = getColorSet();
}
@override
Widget build(BuildContext context) {
double maxWidth = MediaQuery.of(context).size.width;
double maxHeight = MediaQuery.of(context).size.height;
Random randomT = new Random();
int minT = 3;
int maxT = maxHeight.toInt() - 80;
int randomTop = minT randomT.nextInt(maxT - minT);
Random randomL = new Random();
int minL = 3;
int maxL = maxWidth.toInt() - 80;
int randomLeft = minL randomL.nextInt(maxL - minL);
Random randomH = new Random();
int minH = 70;
int maxH = maxHeight.toInt() - randomTop;
int randomHeight = minH randomH.nextInt(maxH - minH);
Random randomW = new Random();
int minW = 70;
int maxW = maxWidth.toInt() - randomLeft;
int randomWidth = minW randomW.nextInt(maxW - minW);
Random randomR = new Random();
int minR = 1;
int maxR = 75;
int randomRadius = minR randomR.nextInt(maxR - minR);
return Stack(
children: [
Container(
child: Positioned(
height: randomHeight.toDouble(),
width: randomWidth.toDouble(),
top: randomTop.toDouble(),
left: randomLeft.toDouble(),
child: SizedBox(
child: ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(colorSet.elementAt(0)),
overlayColor: MaterialStateProperty.all(colorSet.elementAt(1)),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(randomRadius.toDouble()),
side: BorderSide(color: colorSet.elementAt(2), width: 5),
),
),
padding: MaterialStateProperty.all(EdgeInsets.all(10)),
minimumSize: MaterialStateProperty.all(Size(70,70)),
),
onPressed: () {
setState(() {
colorSet = getColorSet();
});
},
child: const Text(
'PRESS',
style: TextStyle(color: Colors.white),
),
),
),
),
),
Container(
child: Positioned(
height: randomHeight.toDouble(),
width: randomWidth.toDouble(),
top: randomTop.toDouble(),
left: randomLeft.toDouble(),
child: SizedBox(
child: ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(colorSet.elementAt(0)),
overlayColor: MaterialStateProperty.all(colorSet.elementAt(1)),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(randomRadius.toDouble()),
side: BorderSide(color: colorSet.elementAt(2), width: 5),
),
),
padding: MaterialStateProperty.all(EdgeInsets.all(10)),
minimumSize: MaterialStateProperty.all(Size(70,70)),
),
onPressed: () {
setState(() {
colorSet = getColorSet();
});
},
child: const Text(
'PRESS',
style: TextStyle(color: Colors.white),
),
),
),
),
),
]
);
}
}
CodePudding user response:
You generated data one time and pass it to two widgets. You should generate data for each button.
Move your button to separate class and generate data there. Then use this class two or several times in your stack.
class MyRandomizedButton extends StatefulWidget {
const MyRandomizedButton({
Key? key,
}) : super(key: key);
static Set<Color> _getColorSet({int numberOfColor = 3}) {
final generatedColorSet = <Color>{};
while (generatedColorSet.length != numberOfColor) {
generatedColorSet.add(
Colors.primaries[Random().nextInt(Colors.primaries.length)],
);
}
return generatedColorSet;
}
@override
State<MyRandomizedButton> createState() => _MyRandomizedButtonState();
}
class _MyRandomizedButtonState extends State<MyRandomizedButton> {
@override
Widget build(BuildContext context) {
final maxWidth = MediaQuery.of(context).size.width;
final maxHeight = MediaQuery.of(context).size.height;
final random = Random();
int minT = 3;
int maxT = maxHeight.toInt() - 80;
int randomTop = minT random.nextInt(maxT - minT);
int minL = 3;
int maxL = maxWidth.toInt() - 80;
int randomLeft = minL random.nextInt(maxL - minL);
int minH = 70;
int maxH = maxHeight.toInt() - randomTop;
int randomHeight = minH random.nextInt(maxH - minH);
int minW = 70;
int maxW = maxWidth.toInt() - randomLeft;
int randomWidth = minW random.nextInt(maxW - minW);
int minR = 1;
int maxR = 75;
int randomRadius = minR random.nextInt(maxR - minR);
final colorSet = MyRandomizedButton._getColorSet();
return Positioned(
height: randomHeight.toDouble(),
width: randomWidth.toDouble(),
top: randomTop.toDouble(),
left: randomLeft.toDouble(),
child: SizedBox(
child: ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(colorSet.elementAt(0)),
overlayColor: MaterialStateProperty.all(colorSet.elementAt(1)),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(randomRadius.toDouble()),
side: BorderSide(color: colorSet.elementAt(2), width: 5),
),
),
padding: MaterialStateProperty.all(const EdgeInsets.all(10)),
minimumSize: MaterialStateProperty.all(const Size(70, 70)),
),
onPressed: () {
setState(() {});
},
child: const Text(
'PRESS',
style: TextStyle(color: Colors.white),
),
),
),
);
}
}
Use:
Stack(
children: [
MyRandomizedButton(key: ValueKey("1")),
MyRandomizedButton(key: ValueKey("2")),
]
)