fix a NestedScrollView's ScrollPosition access bug (#80573)

This commit is contained in:
xubaolin 2021-04-27 01:39:04 +08:00 committed by GitHub
parent ef7b6ffba9
commit cff3211f7f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 48 additions and 6 deletions

View file

@ -1317,6 +1317,7 @@ class _NestedScrollController extends ScrollController {
@override
void detach(ScrollPosition position) {
assert(position is _NestedScrollPosition);
(position as _NestedScrollPosition).setParent(null);
position.removeListener(_scheduleUpdateShadow);
super.detach(position);
_scheduleUpdateShadow();
@ -1621,12 +1622,6 @@ class _NestedScrollPosition extends ScrollPosition implements ScrollActivityDele
Drag drag(DragStartDetails details, VoidCallback dragCancelCallback) {
return coordinator.drag(details, dragCancelCallback);
}
@override
void dispose() {
_parent?.detach(this);
super.dispose();
}
}
enum _NestedBallisticScrollActivityMode { outer, inner, independent }

View file

@ -2342,6 +2342,53 @@ void main() {
expect(isScrolled, false);
expect(tester.takeException(), isNull);
});
// Regression test of https://github.com/flutter/flutter/issues/74372
testWidgets('ScrollPosition can be accessed during `_updatePosition()`', (WidgetTester tester) async {
final ScrollController controller = ScrollController();
late ScrollPosition position;
Widget buildFrame({ScrollPhysics? physics}) {
return Directionality(
textDirection: TextDirection.ltr,
child: Localizations(
locale: const Locale('en', 'US'),
delegates: const <LocalizationsDelegate<dynamic>>[
DefaultMaterialLocalizations.delegate,
DefaultWidgetsLocalizations.delegate,
],
child: MediaQuery(
data: const MediaQueryData(),
child: NestedScrollView(
controller: controller,
physics: physics,
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
Builder(
builder: (BuildContext context) {
position = controller.position;
return const SliverAppBar(
floating: true,
title: Text('AA'),
);
},
),
];
},
body: Container(),
),
),
),
);
}
await tester.pumpWidget(buildFrame());
expect(position.pixels, 0.0);
//Trigger `_updatePosition()`.
await tester.pumpWidget(buildFrame(physics: const _CustomPhysics()));
expect(position.pixels, 0.0);
});
}
class TestHeader extends SliverPersistentHeaderDelegate {