im having some issues with the setState method in flutter.
a little backstory: im making a flutter app that displays how many people are in a room via 5 dots that change colour depending on how many people are in said room. it gets its data via HTTP get requests.
i wish to have my dots automatically update their colour based on the data value, i have tried passing the data variable through the setState() method but it wont update.
is there something wrong with the way im using the setState() method or is it something else?
my code:
i have a statefull dot class as shown below
class Dot extends StatefulWidget {
final int roomnumber;
final int dotnumber; // number of the dot 0-4
const Dot({Key? key,required this.roomnumber, required this.dotnumber});
DotState createState() => DotState();
}
my DotState class looks like this
class Dot extends StatefulWidget {
final int roomnumber;
final int dotnumber; // number of the dot 0-4
const Dot({Key? key,required this.roomnumber, required this.dotnumber});
DotState createState() => DotState();
}
class DotState extends State<Dot> {
HttpHandler httpHandler = new HttpHandler();
@override
void initState() {
new Timer(const Duration(seconds: 1), update);
super.initState();
}
var data = 0;
void update() {
setState(() {
// update the data variable so that it holds the most up to date data
});
}
Widget build(BuildContext context) {
Color dotcolor;
var colorlist = [0xFF8AF107,0xFFFFF50D,0xFFFFC700,0xFFFF900D,0xFFF5430B];
var dotdistribution = [0,5,10,20,40,1000];
var _color = 0xFFFFFFFF;
data = httpHandler.getDataList().elementAt(widget.roomnumber);
for (var p=1;p<5;p++) {
if (data > dotdistribution.elementAt(p)) {
_color = colorlist.elementAt(p-1);
}
}
if (data > dotdistribution.elementAt(widget.dotnumber))
dotcolor = Color(_color);
else dotcolor = Colors.white;
return Container(
decoration: BoxDecoration(
border: Border.all(color: dotcolor),
// TODO: make statefull
color: dotcolor,
borderRadius: BorderRadius.circular(100),
),
width: 15,
height: 15,
margin: EdgeInsets.fromLTRB(2.5, 0, 2.5, 0),
);
}
}
here is the card class and card state containing all 5 dots
class Card extends StatefulWidget {
final String name;
final int roomnumber;
const Card({Key? key, this.name = '', required this.roomnumber}) : super(key: key);
@override
CardState createState() => CardState();
}
class CardState extends State<Card>{
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: Color(0xFFEEEEEEE),
border: Border.all(color: Colors.white),
borderRadius: BorderRadius.circular(10),
),
padding: EdgeInsets.all(10.0),
height: 60,
child: Row(
children: <Widget>[
Expanded(flex: 2,child:
Container(
child: Text(
widget.name,
style: GoogleFonts.inter(
fontWeight: FontWeight.bold,
fontSize: 18,
),
)
)),
Expanded(child:
Row(
children: [
for (var n = 0; n < 5; n++) Dot (
roomnumber: widget.roomnumber,
dotnumber: n,
)
]
)
)
],
),
);
}
}
i have already verified that my httphandler class works as intended so thats not the issue
First of all, you should understand that HTTP requests always won't get a response in 1 second, It's better to say response time isn't constant and depends on a lot of things like network connection quality.
So defining a delay for setting state only works if the response comes before 1 second.
What you should do is waiting for the response to come and then update the state. The best way I can advise for now is using FutureBuilder
.
The FutureBuilder
widget gets a method that returns a Future value like API callbacks and its build function executes after every event that comes from that method.
You can read more about FutureBuilder
in official doc
User contributions licensed under CC BY-SA 3.0