Unverified Commit 602ac0bc authored by Christian Mürtz's avatar Christian Mürtz Committed by GitHub

Fix RefreshIndicator performance issue (#47667)

parent 685e9d1e
...@@ -409,26 +409,26 @@ class RefreshIndicatorState extends State<RefreshIndicator> with TickerProviderS ...@@ -409,26 +409,26 @@ class RefreshIndicatorState extends State<RefreshIndicator> with TickerProviderS
return _pendingRefreshFuture; return _pendingRefreshFuture;
} }
final GlobalKey _key = GlobalKey();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
assert(debugCheckHasMaterialLocalizations(context)); assert(debugCheckHasMaterialLocalizations(context));
final Widget child = NotificationListener<ScrollNotification>( final Widget child = NotificationListener<ScrollNotification>(
key: _key,
onNotification: _handleScrollNotification, onNotification: _handleScrollNotification,
child: NotificationListener<OverscrollIndicatorNotification>( child: NotificationListener<OverscrollIndicatorNotification>(
onNotification: _handleGlowNotification, onNotification: _handleGlowNotification,
child: widget.child, child: widget.child,
), ),
); );
if (_mode == null) { assert(() {
assert(_dragOffset == null); if (_mode == null) {
assert(_isIndicatorAtTop == null); assert(_dragOffset == null);
return child; assert(_isIndicatorAtTop == null);
} } else {
assert(_dragOffset != null); assert(_dragOffset != null);
assert(_isIndicatorAtTop != null); assert(_isIndicatorAtTop != null);
}
return true;
}());
final bool showIndeterminateIndicator = final bool showIndeterminateIndicator =
_mode == _RefreshIndicatorMode.refresh || _mode == _RefreshIndicatorMode.done; _mode == _RefreshIndicatorMode.refresh || _mode == _RefreshIndicatorMode.done;
...@@ -436,7 +436,7 @@ class RefreshIndicatorState extends State<RefreshIndicator> with TickerProviderS ...@@ -436,7 +436,7 @@ class RefreshIndicatorState extends State<RefreshIndicator> with TickerProviderS
return Stack( return Stack(
children: <Widget>[ children: <Widget>[
child, child,
Positioned( if (_mode != null) Positioned(
top: _isIndicatorAtTop ? 0.0 : null, top: _isIndicatorAtTop ? 0.0 : null,
bottom: !_isIndicatorAtTop ? 0.0 : null, bottom: !_isIndicatorAtTop ? 0.0 : null,
left: 0.0, left: 0.0,
......
...@@ -420,4 +420,39 @@ void main() { ...@@ -420,4 +420,39 @@ void main() {
expect(controller.offset, lessThan(0.0)); expect(controller.offset, lessThan(0.0));
expect(refreshCalled, isTrue); expect(refreshCalled, isTrue);
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS })); }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
}
testWidgets('RefreshIndicator does not force child to relayout', (WidgetTester tester) async {
int layoutCount = 0;
Widget layoutCallback(BuildContext context, BoxConstraints constraints) {
layoutCount++;
return ListView(
physics: const AlwaysScrollableScrollPhysics(),
children: <String>['A', 'B', 'C', 'D', 'E', 'F'].map<Widget>((String item) {
return SizedBox(
height: 200.0,
child: Text(item),
);
}).toList(),
);
}
await tester.pumpWidget(
MaterialApp(
home: RefreshIndicator(
onRefresh: refresh,
child: LayoutBuilder(builder: layoutCallback),
),
),
);
await tester.fling(find.text('A'), const Offset(0.0, 300.0), 1000.0); // trigger refresh
await tester.pump();
await tester.pump(const Duration(seconds: 1)); // finish the scroll animation
await tester.pump(const Duration(seconds: 1)); // finish the indicator settle animation
await tester.pump(const Duration(seconds: 1)); // finish the indicator hide animation
expect(layoutCount, 1);
});
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment