For some reasons, the widget associated to the deleted item is also rebuild, which causes an error.
For now, if it occurs, I return an empty container but it is only a quick fix.
import 'package:flutter/material.dart';
import 'package:flutter_widgets/flutter_widgets.dart';
import 'package:provider/provider.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<MyModel>(
builder: (context) => MyModel(),
child: MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('My App')),
body: Container(
padding: const EdgeInsets.only(left: 16.0),
width: 200,
child: Consumer<MyModel>(
builder: (context, myModel, child) {
print('Build ScrollablePositionedList');
print('itemIDs: ${myModel.itemIDs}');
print('itemsMap: ${myModel.itemsMap}');
return ScrollablePositionedList.builder(
scrollDirection: Axis.vertical,
itemCount: myModel.itemIDs.length,
itemBuilder: (BuildContext context, int index) {
final itemID = myModel.itemIDs[index];
return CustomItem(
key: Key('customItem_$itemID'),
itemID: itemID,
);
},
);
},
),
),
),
),
);
}
}
class CustomItem extends StatelessWidget {
const CustomItem({
Key key,
this.itemID,
}) : super(key: key);
final String itemID;
@override
Widget build(BuildContext context) {
final myModel = Provider.of<MyModel>(context);
print('Build CustomItem $itemID');
// DEBUG ********
if (myModel.itemsMap[itemID] == null) {
print('Building a deleted item...');
return Container(
width: 0.0,
height: 0.0,
);
}
// **************
return Row(
children: <Widget>[
Text(myModel.itemsMap[itemID]['label']),
IconButton(
icon: Icon(Icons.delete),
disabledColor: Colors.grey,
onPressed: myModel.itemIDs.length > 1 ? () => myModel.removeItem(itemID) : null,
)
],
);
}
}
class MyModel with ChangeNotifier {
List<String> itemIDs = ['A', 'B', 'C'];
Map<String, Map<String, dynamic>> itemsMap = {
'A': {
'label': 'Item A',
},
'B': {
'label': 'Item B',
},
'C': {
'label': 'Item C',
},
};
void removeItem(itemID) {
print('Remove item $itemID');
final itemIndex = itemIDs.indexWhere((id) => id == itemID);
if (itemIndex > -1) {
itemIDs.removeAt(itemIndex);
itemsMap.remove(itemID);
}
notifyListeners();
}
}