I have a very simple (stateful) widget that contains a Text
widget that displays the length of a list which is a member variable of the widget's state.
Inside the initState()
method, I override the list variable (formerly being null) with a list that has four elements using setState()
. However, the Text
widget still shows "0".
The prints I added imply that a rebuild of the widget has not been triggered although my perception was that this is the sole purpose of the setState()
method.
Here ist the code:
import 'package:flutter/material.dart';
class Scan extends StatefulWidget {
@override
_ScanState createState() => _ScanState();
}
class _ScanState extends State<Scan> {
List<int> numbers;
@override
void initState() {
super.initState();
_initializeController();
}
@override
Widget build(BuildContext context) {
print('Build was scheduled');
return Center(
child: Text(
numbers == null ? '0' : numbers.length.toString()
)
);
}
Future<List<int>> _getAsyncNumberList() {
return Future.delayed(Duration(seconds: 5), () => [1, 2, 3, 4]);
}
_initializeController() async {
List<int> newNumbersList = await _getAsyncNumberList();
print("Number list was updated to list of length ${newNumbersList.length}");
setState(() {
numbers = newNumbersList;
});
}
}
My question: why does the widget only build once? I would have expected to have at least two builds, the second one being triggered by the execution of setState()
.
I have the feeling, the answers don't address my question. My question was why the widget only builds once and why setState() does not trigger a second build.
Answers like "use a FutureBuilder" are not helpful since they completely bypass the question about
setState()
. So no matter how late the async function finishes, triggering a rebuild should update the UI with the new list whensetState()
is executed.Also, the async function does not finish too early (before build has finished). I made sure it does not by trying
WidgetsBinding.instance.addPostFrameCallback
which changed: nothing.I figured out that the problem was somewhere else. In my
main()
function the first two lines were:which somehow affected the build order. But only on my Huawei P20 Lite, on no other of my test devices, not in the emulator and not on Dartpad.
So conclusion: Code is fine. My understanding of
setState()
is also fine. I haven't provided enough context for you to reproduce the error. And my solution was to make the first two lines in themain()
function async: