Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit 213b3cb

Browse files
liumcseTahaTesser
andauthored
Check whether slider is mounted before interaction, no-op if unmounted (#113556)
* Check whether slider is unmounted before interaction * Update slider.dart * Update Slider * Add test * Update slider_test.dart * Update packages/flutter/test/material/slider_test.dart Co-authored-by: Taha Tesser <[email protected]> Co-authored-by: Taha Tesser <[email protected]>
1 parent 3e71e0c commit 213b3cb

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

packages/flutter/lib/src/material/slider.dart

+3
Original file line numberDiff line numberDiff line change
@@ -1528,6 +1528,9 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
15281528

15291529
@override
15301530
void handleEvent(PointerEvent event, BoxHitTestEntry entry) {
1531+
if (!_state.mounted) {
1532+
return;
1533+
}
15311534
assert(debugHandleEvent(event, entry));
15321535
if (event is PointerDownEvent && isInteractive) {
15331536
// We need to add the drag first so that it has priority.

packages/flutter/test/material/slider_test.dart

+55
Original file line numberDiff line numberDiff line change
@@ -3437,6 +3437,61 @@ void main() {
34373437
);
34383438
}, variant: TargetPlatformVariant.desktop());
34393439

3440+
testWidgets('Event on Slider should perform no-op if already unmounted', (WidgetTester tester) async {
3441+
// Test covering crashing found in Google internal issue b/192329942.
3442+
double value = 0.0;
3443+
final ValueNotifier<bool> shouldShowSliderListenable =
3444+
ValueNotifier<bool>(true);
3445+
3446+
await tester.pumpWidget(
3447+
MaterialApp(
3448+
home: Directionality(
3449+
textDirection: TextDirection.ltr,
3450+
child: StatefulBuilder(
3451+
builder: (BuildContext context, StateSetter setState) {
3452+
return Material(
3453+
child: Center(
3454+
child: ValueListenableBuilder<bool>(
3455+
valueListenable: shouldShowSliderListenable,
3456+
builder: (BuildContext context, bool shouldShowSlider, _) {
3457+
return shouldShowSlider
3458+
? Slider(
3459+
value: value,
3460+
onChanged: (double newValue) {
3461+
setState(() {
3462+
value = newValue;
3463+
});
3464+
},
3465+
)
3466+
: const SizedBox.shrink();
3467+
},
3468+
),
3469+
),
3470+
);
3471+
},
3472+
),
3473+
),
3474+
),
3475+
);
3476+
3477+
final TestGesture gesture = await tester
3478+
.startGesture(tester.getRect(find.byType(Slider)).centerLeft);
3479+
3480+
// Intentioanlly not calling `await tester.pumpAndSettle()` to allow drag
3481+
// event performed on `Slider` before it is about to get unmounted.
3482+
shouldShowSliderListenable.value = false;
3483+
3484+
await tester.drag(find.byType(Slider), const Offset(1.0, 0.0));
3485+
await tester.pumpAndSettle();
3486+
3487+
expect(value, equals(0.0));
3488+
3489+
// This is supposed to trigger animation on `Slider` if it is mounted.
3490+
await gesture.up();
3491+
3492+
expect(tester.takeException(), null);
3493+
});
3494+
34403495
group('Material 2', () {
34413496
// Tests that are only relevant for Material 2. Once ThemeData.useMaterial3
34423497
// is turned on by default, these tests can be removed.

0 commit comments

Comments
 (0)