Reputation: 1553
In my Flutter app,
I want to display multiple items inside a listView,
and I want to handle their state using Provider.
But how can I handle the state in a way that if I edit one item in the listview, then only that item gets rebuild,
and the entire listview gets rebuild only when I change the number of items either by adding or deleting.
How can I do this?
Upvotes: 4
Views: 3650
Reputation: 4129
This is a working solution that is very close to what you want (It still rebuilds the whole ListView
when one item is edited but have no worries about efficiency because ListView.builder
takes care of that for you):
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class MyModel {
int modelNumber;
MyModel(this.modelNumber);
void edit(int newModelNumber) {
modelNumber = newModelNumber;
}
}
class MyModelListWrapper with ChangeNotifier {
List<MyModel> modelsList;
MyModelListWrapper(this.modelsList);
void add(MyModel model) {
modelsList.add(model);
notifyListeners();
}
void removeAt(int index) {
modelsList.removeAt(index);
notifyListeners();
}
void editModelNumber(int index,int newModelNumber){
modelsList[index].edit(newModelNumber);
notifyListeners();
}
}
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(
create: (_) => MyModelListWrapper(
[...List.generate(15, (index)=>MyModel(index))]),
),
],
child: MaterialApp(
home: HomePage(),
),
);
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Consumer<MyModelListWrapper>(
builder: (_,myModelsListWrapper,__)=> ListView.builder(
itemCount: myModelsListWrapper.modelsList.length,
itemBuilder: (ctx, index) => ListTile(
title: Text('${myModelsListWrapper.modelsList[index].modelNumber}'),
onTap: (){
// myModelsListWrapper.editModelNumber(index, -1);
myModelsListWrapper.removeAt(index);
//or do any other action you want
},
),
),
),
);
}
}
Upvotes: 3