Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter: Management of the state of multiple items in a list view using ChangeNotifierProvider

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?

like image 455
Karrar Avatar asked Nov 07 '25 06:11

Karrar


1 Answers

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
            },
          ),
        ),
      ),
    );
  }
}
like image 100
Haidar Avatar answered Nov 09 '25 02:11

Haidar



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!