I solved this problem with a statefull widget to represent a item in ListView. If you want manipulate just a item data, you do it by Item widget. If you add or remove a item on the tail of list, the list will be not rerendered.
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
import 'package:random_color/random_color.dart';
RandomColor randomColor = RandomColor();
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final wordPair = WordPair.random(); // Add this line.
return MaterialApp(
title: 'Welcome to Flutter',
home: Numbers(),
debugShowCheckedModeBanner: false,
);
}
}
/**
* View
*/
class Numbers extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return NumbersState();
}
}
/**
* Item
*/
class Item extends StatefulWidget {
int value;
Item({this.value});
@override
State<StatefulWidget> createState() {
// TODO: implement createState
return ItemState();
}
}
class ItemState extends State<Item> {
@override
Widget build(BuildContext context) {
return Container(
color: randomColor.randomColor(colorBrightness: ColorBrightness.light),
child: ListTile(
title: Text(widget.value.toString()),
onTap: () {
setState(() {
widget.value++;
});
},
),
);
}
}
/**
* List
*/
class NumbersState extends State<Numbers> {
List<Item> numbers = new List<Item>();
String message = "Teste";
void addItem(int v) {
Item i = Item(value: v,);
numbers.add(i);
setState(() {});
}
Stream generateNumbers() async* {
for (int i in List.generate(5, (i) => i)) {
yield i;
}
}
@override
void initState() {
// super.initState();
generateNumbers().listen((dynamic i) {
print(i);
Timer(Duration(seconds: 0), () {
addItem(i);
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
// Add from here...
appBar: AppBar(
title: Text('ListView'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.ac_unit),
onPressed: () {
setState(() {
message = "Teste";
});
},
),
IconButton(
icon: Icon(Icons.arrow_upward),
onPressed: () {
setState(() {
message = "Teste";
});
},
),
IconButton(
icon: Icon(Icons.arrow_downward),
onPressed: () {
setState(() {
message = "Teste";
});
},
),
IconButton(
icon: Icon(Icons.add),
onPressed: () {
addItem(1);
},
),
IconButton(
icon: Icon(Icons.remove),
onPressed: () {
numbers.removeAt(numbers.length-1);
setState(() {});
},
)
],
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
padding: EdgeInsets.all(16),
child: Text("Teste de ListView: \n 1. Atualizar item\n 2. Navegação\n 3. Movimento"),
),
Expanded(
child: ListView.builder(
reverse: true,
itemCount: numbers.length,
itemBuilder: (context, int i) {
return numbers[i];
})
)
],
),
); // ... to here.
}
}