From 25ef78e23493ee0045a8e28d9daa1ded12f62a7c Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 24 Mar 2020 17:56:01 -0700 Subject: [PATCH] Revert "Revert "Fix RefreshIndicator performance issue (#47667)" (#53149)" (#53206) --- .../lib/src/material/refresh_indicator.dart | 22 +++++------ .../test/material/refresh_indicator_test.dart | 37 ++++++++++++++++++- 2 files changed, 47 insertions(+), 12 deletions(-) diff --git a/packages/flutter/lib/src/material/refresh_indicator.dart b/packages/flutter/lib/src/material/refresh_indicator.dart index d63b33a2ea..85212839c4 100644 --- a/packages/flutter/lib/src/material/refresh_indicator.dart +++ b/packages/flutter/lib/src/material/refresh_indicator.dart @@ -409,26 +409,26 @@ class RefreshIndicatorState extends State with TickerProviderS return _pendingRefreshFuture; } - final GlobalKey _key = GlobalKey(); - @override Widget build(BuildContext context) { assert(debugCheckHasMaterialLocalizations(context)); final Widget child = NotificationListener( - key: _key, onNotification: _handleScrollNotification, child: NotificationListener( onNotification: _handleGlowNotification, child: widget.child, ), ); - if (_mode == null) { - assert(_dragOffset == null); - assert(_isIndicatorAtTop == null); - return child; - } - assert(_dragOffset != null); - assert(_isIndicatorAtTop != null); + assert(() { + if (_mode == null) { + assert(_dragOffset == null); + assert(_isIndicatorAtTop == null); + } else { + assert(_dragOffset != null); + assert(_isIndicatorAtTop != null); + } + return true; + }()); final bool showIndeterminateIndicator = _mode == _RefreshIndicatorMode.refresh || _mode == _RefreshIndicatorMode.done; @@ -436,7 +436,7 @@ class RefreshIndicatorState extends State with TickerProviderS return Stack( children: [ child, - Positioned( + if (_mode != null) Positioned( top: _isIndicatorAtTop ? 0.0 : null, bottom: !_isIndicatorAtTop ? 0.0 : null, left: 0.0, diff --git a/packages/flutter/test/material/refresh_indicator_test.dart b/packages/flutter/test/material/refresh_indicator_test.dart index b24097e62a..17a5da2714 100644 --- a/packages/flutter/test/material/refresh_indicator_test.dart +++ b/packages/flutter/test/material/refresh_indicator_test.dart @@ -420,4 +420,39 @@ void main() { expect(controller.offset, lessThan(0.0)); expect(refreshCalled, isTrue); }, variant: const TargetPlatformVariant({ 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: ['A', 'B', 'C', 'D', 'E', 'F'].map((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