ccd
ccd

Reputation: 6948

How to update UI when remove and add list item with provider

I have a list items in provider model, and i want to set a observer listener to it when i add or remove item, while update part of related UI in the stateless widget (not with setState in Stateful widget).

// Provider
class AppState extends ChangeNotifier {
  List<Item> _items;
  List<Item> get items => _items;
  Future<void> addItem(...) async {
    ...
    notifyListeners();
  }
  Future<void> deleteItem(...) async {
    ...
    notifyListeners();
  }
}

// UI
class _itemList extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var appState = context.watch<AppState>();  // If I watch the list, it will rebuild all of it.
    return ListView.builder(
      itemCount: appState.items.length,
      itemBuilder: (context, index) {
        final item = appState.items[index];
        return ListTile(  // How to observer the item of list instead to rebuild all of it?
          title: Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Text(item.name),
              Icon(Icons.keyboard_arrow_right, color: Colors.grey)
            ],
          )
      });
  }
}

Upvotes: 1

Views: 1747

Answers (1)

sameer kashyap
sameer kashyap

Reputation: 1166

  • Use with with ChangeNotifier and not extends as ChangeNotifier is a mixin and not a class.

  • Not sure if you can observe an individual item with the current setup you have as you have a List of items in your Changenotifier and that's the only property holding state. Although, there is another way you can use to observe a single property using provider using context.select<AppState>((appState) =>appState.items) , this will watch only the items.

  • However, if you want to also maintain a state of an individual item which is helpful when you're trying to see the content of a single item on another screen, you can do this

class AppState with ChangeNotifier {
  List<Item> _items;
  List<Item> get items => _items;
  
   Item _item;
   Item get item => _item;


   setCurrentItem(int index){
      _item= _tems[index];
      notifyListners();
   }

...

 @override
  Widget build(BuildContext context) {
    var item = context.select<AppState>((appSatet)=> appState.item);


// set the item using setCurrentItem() to observe one item.

But since you're rendering a list of Items, whatever you're doing is right and any mutation to the list would have to rebuild the entire list and not just one item unless you're only displaying one item.

Upvotes: 1

Related Questions