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.
3
Answers
So, I solved my problem by creating a separate provider
DevicesProvider
that contains the list of devices modified in the room. I provide the current room by calling the methodSetCurrentRoom(String currentRoomIdentifier)
from theDetailPage
and the provider does its job whenever the devices list in the current room updates.Maybe this can be solved in a different way which is more elegant or efficient, but for now my problem is solved with this approach.
To only rebuild the specific widget, you can wrap that widget inside
Consumer
widget provider byProvider
in flutter.Consumer
takes a builder function and will build the widget returned by this builder function only when the data changes.To implement this, you can use a Comsumer widget
A StatelessWidget is also sufficient. Don’t forget the index by room. It should work like this