1

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)
            ],
          )
      });
  }
}
1
  • 1
    The best way to do this is by using streams in dart. Try learning the bloc pattern. Provider has a different use and it is not for rebuilding specific widgets. Try learning how streams work in flutter and flutter_bloc or rxdart Commented Dec 9, 2020 at 7:02

1 Answer 1

1
  • 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.

Sign up to request clarification or add additional context in comments.

1 Comment

Note that the value retured from context.select() needs to be immutable, otherwise Selector can not detect changes. pub.dev/documentation/provider/latest/provider/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.