Bonjour à tous,
J’ai vu passer quelques sujets concernant les performances et je me pose une question depuis un moment concernant les AnimatedBuilder (maintenant ListenableBuilder).
Si j’ai une page avec plusieurs champs dynamiques (par expl une page de configuration) a chaque fois que je fait appel au notifyListener
de mon Viewmodel je vais recharger toute la page, mais est il vraiment necessaire de recharger des zones qui ne sont pas modifiées ?
J’imagine dans le futur indégrer des « enfants » à mon Viewmodel pour découper et recharger uniquement les zones modifiées (je met un exemple en dessous) mais cela vaut il vraiment le coup ? Gagne t’on en performance ?
Exemple :
my_page.dart
import 'package:flutter/material.dart';
import 'package:pgtest/viewmodel.dart';
class MyPage extends StatelessWidget {
MyPage({super.key});
final MyViewmodel _viewmodel = MyViewmodel();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: ListenableBuilder(
listenable: _viewmodel.titlePage,
builder: (context, _) {
print("BUILD APPBAR");
return Text(_viewmodel.titlePage.value);
},
),
),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"MA SUPER PAGE",
style: Theme.of(context).textTheme.titleMedium,
),
ListenableBuilder(
listenable: _viewmodel.titlePage,
builder: (context, _) {
print("BUILD Saisie titre page");
return TextField(
onSubmitted: _viewmodel.titlePage.change,
decoration: InputDecoration(
hintText: _viewmodel.titlePage.value,
labelText: "Titre de la page:",
),
);
},
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text("Une option 1"),
ListenableBuilder(
listenable: _viewmodel.option1,
builder: (context, _) {
print("BUILD option 1");
return Switch(
value: _viewmodel.option1.value,
onChanged: _viewmodel.option1.change,
);
},
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text("Une autre option"),
ListenableBuilder(
listenable: _viewmodel.option2,
builder: (context, _) {
print("BUILD option 2");
return Switch(
value: _viewmodel.option2.value,
onChanged: _viewmodel.option2.change,
);
},
),
],
),
ElevatedButton(
onPressed: _viewmodel.notify,
child: const Text("Recharger Viewmodel"),
),
],
),
),
),
);
}
}
my_viewmodel.dart
import 'package:flutter/material.dart';
class MyViewmodel extends ChangeNotifier {
final MyViewmodelTitlePage titlePage = MyViewmodelTitlePage();
final MyViewmodelOption1 option1 = MyViewmodelOption1();
final MyViewmodelOption2 option2 = MyViewmodelOption2();
// On garde la possibilité de rechager tous les notifyListener d'un coup
@override
void notifyListeners() {
titlePage.notifyListeners();
option1.notifyListeners();
option2.notifyListeners();
super.notifyListeners();
}
// Pour l'appel depuis la page
void notify() => notifyListeners();
}
class MyViewmodelTitlePage extends ChangeNotifier {
String _titlePage = "SUPER APP!";
String get value => _titlePage;
void change(String value) {
_titlePage = value;
notifyListeners();
}
}
class MyViewmodelOption1 extends ChangeNotifier {
bool _option1 = false;
bool get value => _option1;
void change(bool val) {
_option1 = val;
notifyListeners();
}
}
class MyViewmodelOption2 extends ChangeNotifier {
bool _option2 = false;
bool get value => _option2;
void change(bool val) {
_option2 = val;
notifyListeners();
}
}