import 'dart:math';
import 'package:flutter/material.dart';
void main() {
return runApp(
MaterialApp(
home: Scaffold(
backgroundColor: Colors.red,
appBar: AppBar(
title: Text('Dicee'),
backgroundColor: Colors.red,
),
body: DicePage(),
),
),
);
}
class DicePage extends StatefulWidget {
@override
State<DicePage> createState() => _DicePageState();
}
class _DicePageState extends State<DicePage> {
@override
Widget build(BuildContext context) {
return Center(
child: Row(
children: [
Die(DiePosition.Left),
Die(DiePosition.Right),
],
),
);
}
}
enum DiePosition {
Right,
Left,
}
class Die extends StatefulWidget {
final DiePosition diePosition;
Die(this.diePosition);
@override
State<Die> createState() => _DieState();
}
class _DieState extends State<Die> {
Map<DiePosition, int> dieNumbers = {
DiePosition.Left: 1,
DiePosition.Right: 1
}; //
Random rd = Random();
@override
Widget build(BuildContext context) {
return Expanded(
child: TextButton(
child: Image.asset(
'images/dice${widget.diePosition == DiePosition.Left ? dieNumbers[DiePosition.Left] : dieNumbers[DiePosition.Right]}.png',
),
onPressed: () {
setBothDiceState(rd);
print(
'${widget.diePosition.toString()} pressed! LB: ${dieNumbers[DiePosition.Left]} RB: ${dieNumbers[DiePosition.Right]}');
},
),
);
}
void setBothDiceState(Random rd) {
setState(() {
dieNumbers[DiePosition.Left] = rd.nextInt(6) + 1; // 1...6
dieNumbers[DiePosition.Right] = rd.nextInt(6) + 1;
}); // 1 - 6
}
}
There are two Die instances in a row on the DicePage and I wish that whenever a press either of the dice, both update on screen.
However only the one I press updates on screen, in spite of both of the dieNumbers in the Map updating as expected.
Everything was working as expected until I tried to extract the Die class from the DicePage. I can't figure out how to rebuild both instances on the DicePage.
I made minimum changes so it should work like you want
import 'dart:math';
import 'package:flutter/material.dart';
void main() {
return runApp(
MaterialApp(
home: Scaffold(
backgroundColor: Colors.red,
appBar: AppBar(
title: Text('Dicee'),
backgroundColor: Colors.red,
),
body: DicePage(),
),
),
);
}
class DicePage extends StatefulWidget {
@override
State<DicePage> createState() => _DicePageState();
}
class _DicePageState extends State<DicePage> {
@override
Widget build(BuildContext context) {
return Center(
child: Row(
children: [
Die(DiePosition.Left, setState),
Die(DiePosition.Right, setState),
],
),
);
}
}
enum DiePosition {
Right,
Left,
}
class Die extends StatefulWidget {
final DiePosition diePosition;
Function(VoidCallback) setParent;
Die(this.diePosition, this.setParent);
@override
State<Die> createState() => _DieState();
}
class _DieState extends State<Die> {
static Map<DiePosition, int> dieNumbers = {
DiePosition.Left: 1,
DiePosition.Right: 1
}; //
Random rd = Random();
@override
Widget build(BuildContext context) {
return Expanded(
child: TextButton(
child: Image.asset(
'images/dice${widget.diePosition == DiePosition.Left ? dieNumbers[DiePosition.Left] : dieNumbers[DiePosition.Right]}.png',
),
onPressed: () {
setBothDiceState(rd);
print(
'${widget.diePosition.toString()} pressed! LB: ${dieNumbers[DiePosition.Left]} RB: ${dieNumbers[DiePosition.Right]}');
},
),
);
}
void setBothDiceState(Random rd) {
widget.setParent(() {
dieNumbers[DiePosition.Left] = rd.nextInt(6) + 1; // 1...6
dieNumbers[DiePosition.Right] = rd.nextInt(6) + 1;
}); // 1 - 6
}
}
So what I did is that each Die gets the function passed that calls setState for the parent. This way calling that will update both. Furthermore it was necessary to make the dieNumbers
static because otherwise each Die has their own map