Home > database >  Flutter using Provider - context.watch<T>() for specific items in a list and ignores the other
Flutter using Provider - context.watch<T>() for specific items in a list and ignores the other

Time:01-28

I am a newbie in Flutter and I am trying to build an app using Provider. I will try to provide an oversimplified example here. My app includes a model of a room.

class Room {
String roomDisplayName;
String roomIdentifier;
Image image;
List<IDevices> devices = [];

Room(this.roomDisplayName, this.roomIdentifier, this.image, this.devices);
}

Rooms have list of devices like a temperature sensor

class TempSensor implements IDevices {
late String tempSensorName;
late double temperatureValue;
late double humidityValue;
late int battery;

TempSensor(this.displayName, this.zigbeeFriendlyName);

UpdateTempSensor(double temperature, double humidiy, int battery) {
  this.temperatureValue = temperature;
  this.humidityValue = humidiy;
  this.battery = battery;
}

I have a RoomProvider class that implements ChangeNotifier that is responsible for updating devices in List<Room> rooms

class RoomsRepositoryProvider with ChangeNotifier {

List<Room> get rooms {
//return _rooms;
return _rooms;
}

  UpdateTemperatureSensor(TempSensor tempSensor) {
  TempSensor? foundTempSensor = null;
  _rooms.forEach((room) {
    room.devices.forEach((element) {
      if (element.displayName == tempSensor.displayName) {
        foundTempSensor = element as TempSensor;
      }
    });
  });
  if (foundTempSensor != null) {
    foundTempSensor?.UpdateTempSensor(tempSensor.temperatureValue,
        tempSensor.humidityValue, tempSensor.battery);
    notifyListeners();
  }
}

I also have a Stateful widget page to show Room information like temperature/humidity value.

class DetailPage extends StatefulWidget {
final Room room;

DetailPage({required this.room});

@override
_DetailPageState createState() => _DetailPageState();
}

class _DetailPageState extends State<DetailPage> {
@override
Widget build(BuildContext context) {
context.watch<RoomsRepositoryProvider>().rooms;
return Text ("Temperature is ${widget.room.devices[0].temperatureValue}");
}

Here is question:

The problem I am facing is that, if I am showing the Living Room in DetailPage and the temperature sensor from Bedroom gets updated in the List<Room> rooms, the whole DetailPage gets rebuild. Since it is not an issue in the flutter and the app works good. I would still like to know how to solve this architecture problem, that the DetailPage only gets build for the room updates related to the room being shown?

PS: please ignore any build, indentation or naming convention mistakes.

CodePudding user response:

To only rebuild the specific widget, you can wrap that widget inside Consumer widget provider by Provider in flutter. Consumer takes a builder function and will build the widget returned by this builder function only when the data changes.

Consumer(
   builder:(context,_,__){
     return Container();
  },
),

CodePudding user response:

To implement this, you can use a Comsumer widget

Consumer<RoomsRepositoryProvider>(
builder:(context,value,child) => Text("Temperature is ${value.room}");
),

A StatelessWidget is also sufficient. Don't forget the index by room. It should work like this

  • Related