Reputation: 4800
On the screen I expect to see an ever growing list:
but it's just black. If I hit CTRL+S in Android Studio all of a sudden the whole list is finally shown.
import 'dart:async';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
List<Widget> list = [];
@override
Widget build(BuildContext context) {
print('${list.length}');
return MaterialApp(
home: ListView(
children: list,
),
);
}
@override
void initState() {
super.initState();
new Timer.periodic(const Duration(seconds: 1), (timer) {
setState(() {
list.add(Text('${list.length}', key: Key(list.length.toString())));
});
});
}
}
At first I thought it was because I wasn't setting key property, but I added that and still nothing.
I know the build() property is being triggered every second because I see the print() statement showing the numbers in the debug Run tab output.
What am I missing here? It's got to be something simple!
Upvotes: 2
Views: 181
Reputation: 7502
You need to 'key' parameter to 'ListView' widget.
With below code, I confirmed working what you want.
I think that because you add a 'key' to Text widget, 'ListView' widget didn't rebuild.
import 'dart:async';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
List<Widget> list = [];
@override
Widget build(BuildContext context) {
print('${list.length}');
return MaterialApp(
home: ListView(
key: UniqueKey(),
children: list,
),
);
}
@override
void initState() {
super.initState();
new Timer.periodic(const Duration(seconds: 1), (timer) {
setState(() {
list.add(Text('${list.length}', key: Key(list.length.toString())));
});
});
}
}
Or you can do it also by changing 'ListView' to 'ListView.builder'.
ListView.builder(
itemCount: list.length,
itemBuilder: (context, index) {
return list[index];
},
),
);
Upvotes: 1
Reputation: 6430
Interesting discovery.
What is actually causing your UI to not update is that the reference to the list
variable is staying the same.
Adding an element, doesn't change the reference and ListView
seems to work based on references.
Two ways you can confirm this are.
Change your ListView
to a much simpler Column
widget and voila, it's updating correctly.
Change your updation method. Destroy the reference and make a new List
like this,
list = [...list, Text('${list.length}')];
and yet again, surprise.
Upvotes: 2