Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter Provider: notifyListeners() to specific target

Background info:

For my flutter project, I am using listview.builder and provider:

ListView.Builder: getting the buttons info using provider and listen is false.

@override
Widget build(BuildContext context) {
final buttons = Provider.of<mybuttons>(context, listen: false);

return Container(    
  child: ListView.builder(
    itemCount: buttons.length,
    itemBuilder: (context, index) {
      return singleButton(listIndex: index);
    },
  ),
 );
}

Then... where, singleButton(): This will run according to the length from the parent widget.

@override
Widget build(BuildContext context) {
final singleButtonInfo = Provider.of<mybuttons>(context).buttonIndex[listIndex];

return FlatButton(
  child: Text(singleButtonInfo.text),
  onTap: (){
       changeText(listIndex);
  }
 );
}

Thus, if the length is 5, then there will be 5 flatbuttons with index from 0 to 4.

Using the onTapfunction, I want to change the text of that specific button (ie. if 3rd button is clicked, then I want to change only the 3rd button without rebuilding all buttons).

changeText(int listIndex){
  ...logic
  notifyListeners();
}

Here is question:

My understanding of notifyListeners() is that it will notify everything with the Provider.of<T>(context)and those widgets will be rebuilt (ie. all 5 buttons will be rebuilt with the new data).

Because each button will have an unique index, is there a way to target a specific button to be rebuilt and ignore the rest?

Thanks!

like image 946
Steve Kim Avatar asked Nov 27 '19 21:11

Steve Kim


People also ask

What does notifyListeners do in Flutter?

That means you can subscribe to a class that is extended or mixed in with ChangeNotifier and call its notifyListeners() method when there's a change in that class. This call will notify the widgets that are subscribed to this class to rebuild.


1 Answers

First, note that the optimization that you're trying to do is, most of the time, pointless.

Optimizing rebuilds has usually very little benefits, and may not be worth the added complexity and is useful only when the states change at a very frequent rate (like animations).

That said, what you're looking for is Selector.

Selector is a custom may of consuming providers which, as opposed to Consumer/Provider.of, has a way to filter undesired updates.

For example, if a widget only needs MyModel.text, then instead of:

final model = Provider.of<MyModel>(context);

return Text(model.text);

we can use Selector like so:

return Selector<MyModel, String>(
  selector: (_, model) => model.text,
  builder: (_, text, __) {
    return Text(text);
  }
);

Such code will call builder again only when MyModel.text changes, and ignores changes to anything else.

like image 152
Rémi Rousselet Avatar answered Sep 24 '22 14:09

Rémi Rousselet