refact: flutter, ChangeNotifier, reduce rebuild (#9392)
Signed-off-by: fufesou <linlong1266@gmail.com>
This commit is contained in:
parent
88a99211f3
commit
c6e3f60a6b
@ -250,6 +250,9 @@ class _PeerCardState extends State<_PeerCard>
|
|||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
margin: EdgeInsets.zero,
|
margin: EdgeInsets.zero,
|
||||||
|
// to-do: memory leak here, more investigation needed.
|
||||||
|
// Continious rebuilds of `Obx()` will cause memory leak here.
|
||||||
|
// The simple demo does not have this issue.
|
||||||
child: Obx(
|
child: Obx(
|
||||||
() => Container(
|
() => Container(
|
||||||
foregroundDecoration: deco.value,
|
foregroundDecoration: deco.value,
|
||||||
|
@ -108,7 +108,7 @@ class _PeerTabPageState extends State<PeerTabPage>
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final model = Provider.of<PeerTabModel>(context);
|
final model = Provider.of<PeerTabModel>(context);
|
||||||
Widget selectionWrap(Widget widget) {
|
Widget selectionWrap(Widget widget) {
|
||||||
return model.multiSelectionMode ? createMultiSelectionBar() : widget;
|
return model.multiSelectionMode ? createMultiSelectionBar(model) : widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
@ -362,8 +362,7 @@ class _PeerTabPageState extends State<PeerTabPage>
|
|||||||
.toList());
|
.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget createMultiSelectionBar() {
|
Widget createMultiSelectionBar(PeerTabModel model) {
|
||||||
final model = Provider.of<PeerTabModel>(context);
|
|
||||||
return Row(
|
return Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
@ -381,7 +380,7 @@ class _PeerTabPageState extends State<PeerTabPage>
|
|||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
selectionCount(model.selectedPeers.length),
|
selectionCount(model.selectedPeers.length),
|
||||||
selectAll(),
|
selectAll(model),
|
||||||
closeSelection(),
|
closeSelection(),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@ -512,8 +511,7 @@ class _PeerTabPageState extends State<PeerTabPage>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget selectAll() {
|
Widget selectAll(PeerTabModel model) {
|
||||||
final model = Provider.of<PeerTabModel>(context);
|
|
||||||
return Offstage(
|
return Offstage(
|
||||||
offstage:
|
offstage:
|
||||||
model.selectedPeers.length >= model.currentTabCachedPeers.length,
|
model.selectedPeers.length >= model.currentTabCachedPeers.length,
|
||||||
|
@ -167,6 +167,9 @@ class _PeersViewState extends State<_PeersView>
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
// We should avoid too many rebuilds. MacOS(m1, 14.6.1) on Flutter 3.19.6.
|
||||||
|
// Continious rebuilds of `ChangeNotifierProvider` will cause memory leak.
|
||||||
|
// Simple demo can reproduce this issue.
|
||||||
return ChangeNotifierProvider<Peers>(
|
return ChangeNotifierProvider<Peers>(
|
||||||
create: (context) => widget.peers,
|
create: (context) => widget.peers,
|
||||||
child: Consumer<Peers>(builder: (context, peers, child) {
|
child: Consumer<Peers>(builder: (context, peers, child) {
|
||||||
@ -245,6 +248,9 @@ class _PeersViewState extends State<_PeersView>
|
|||||||
: Container(child: visibilityChild);
|
: Container(child: visibilityChild);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We should avoid too many rebuilds. Win10(Some machines) on Flutter 3.19.6.
|
||||||
|
// Continious rebuilds of `ListView.builder` will cause memory leak.
|
||||||
|
// Simple demo can reproduce this issue.
|
||||||
final Widget child = Obx(() => stateGlobal.isPortrait.isTrue
|
final Widget child = Obx(() => stateGlobal.isPortrait.isTrue
|
||||||
? ListView.builder(
|
? ListView.builder(
|
||||||
itemCount: peers.length,
|
itemCount: peers.length,
|
||||||
|
@ -184,10 +184,17 @@ class PeerTabModel with ChangeNotifier {
|
|||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// `notifyListeners()` will cause many rebuilds.
|
||||||
|
// So, we need to reduce the calls to "notifyListeners()" only when necessary.
|
||||||
|
// A better way is to use a new model.
|
||||||
setCurrentTabCachedPeers(List<Peer> peers) {
|
setCurrentTabCachedPeers(List<Peer> peers) {
|
||||||
Future.delayed(Duration.zero, () {
|
Future.delayed(Duration.zero, () {
|
||||||
|
final isPreEmpty = _currentTabCachedPeers.isEmpty;
|
||||||
_currentTabCachedPeers = peers;
|
_currentTabCachedPeers = peers;
|
||||||
notifyListeners();
|
final isNowEmpty = _currentTabCachedPeers.isEmpty;
|
||||||
|
if (isPreEmpty != isNowEmpty) {
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user