Fix: Range slider show overlay for both thumbs on hovering one (#165393)
Fix: Range slider show overlay for both thumbs on hovering one fixes: #165281 ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing.
This commit is contained in:
@@ -1517,8 +1517,8 @@ class _RenderRangeSlider extends RenderBox with RelayoutWhenSystemFontsChangeMix
|
||||
isEnabled: isEnabled,
|
||||
);
|
||||
|
||||
final bool startThumbSelected = _lastThumbSelection == Thumb.start;
|
||||
final bool endThumbSelected = _lastThumbSelection == Thumb.end;
|
||||
final bool startThumbSelected = _lastThumbSelection == Thumb.start && !hoveringEndThumb;
|
||||
final bool endThumbSelected = _lastThumbSelection == Thumb.end && !hoveringStartThumb;
|
||||
final Size resolvedscreenSize = screenSize.isEmpty ? size : screenSize;
|
||||
|
||||
if (!_overlayAnimation.isDismissed) {
|
||||
|
||||
@@ -2810,4 +2810,140 @@ void main() {
|
||||
|
||||
semantics.dispose();
|
||||
}, semanticsEnabled: false);
|
||||
|
||||
testWidgets('RangeSlider overlay appears correctly for specific thumb interactions', (
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
|
||||
RangeValues values = const RangeValues(50, 70);
|
||||
const Color hoverColor = Color(0xffff0000);
|
||||
const Color dragColor = Color(0xff0000ff);
|
||||
|
||||
Widget buildApp() {
|
||||
return MaterialApp(
|
||||
home: Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: StatefulBuilder(
|
||||
builder: (BuildContext context, StateSetter setState) {
|
||||
return Material(
|
||||
child: Center(
|
||||
child: RangeSlider(
|
||||
values: values,
|
||||
max: 100.0,
|
||||
overlayColor: WidgetStateProperty.resolveWith<Color?>((
|
||||
Set<WidgetState> states,
|
||||
) {
|
||||
if (states.contains(WidgetState.hovered)) {
|
||||
return hoverColor;
|
||||
}
|
||||
if (states.contains(WidgetState.dragged)) {
|
||||
return dragColor;
|
||||
}
|
||||
|
||||
return null;
|
||||
}),
|
||||
onChanged: (RangeValues newValues) {
|
||||
setState(() {
|
||||
values = newValues;
|
||||
});
|
||||
},
|
||||
onChangeStart: (RangeValues newValues) {},
|
||||
onChangeEnd: (RangeValues newValues) {},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
await tester.pumpWidget(buildApp());
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Initial state - no overlay.
|
||||
expect(
|
||||
Material.of(tester.element(find.byType(RangeSlider))),
|
||||
isNot(paints..circle(color: dragColor)),
|
||||
);
|
||||
|
||||
// Drag start thumb to left.
|
||||
final Offset topThumbLocation = tester.getCenter(find.byType(RangeSlider));
|
||||
final TestGesture dragStartThumb = await tester.startGesture(topThumbLocation);
|
||||
await tester.pump(kPressTimeout);
|
||||
await dragStartThumb.moveBy(const Offset(-20.0, 0));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Verify overlay is visible and shadow is visible on single thumb.
|
||||
expect(
|
||||
Material.of(tester.element(find.byType(RangeSlider))),
|
||||
paints
|
||||
..circle(color: dragColor)
|
||||
..path(color: Colors.black, style: PaintingStyle.stroke, strokeWidth: 2.0)
|
||||
..path(color: Colors.black, style: PaintingStyle.stroke, strokeWidth: 12.0),
|
||||
);
|
||||
|
||||
// Move back and release.
|
||||
await dragStartThumb.moveBy(const Offset(20.0, 0));
|
||||
await dragStartThumb.up();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Verify overlay and shadow disappears
|
||||
expect(
|
||||
Material.of(tester.element(find.byType(RangeSlider))),
|
||||
isNot(
|
||||
paints
|
||||
..circle(color: dragColor)
|
||||
..path(color: Colors.black, style: PaintingStyle.stroke, strokeWidth: 2.0)
|
||||
..path(color: Colors.black, style: PaintingStyle.stroke, strokeWidth: 2.0),
|
||||
),
|
||||
);
|
||||
|
||||
// Drag end thumb and return to original position.
|
||||
final Offset bottomThumbLocation = tester
|
||||
.getCenter(find.byType(RangeSlider))
|
||||
.translate(220.0, 0.0);
|
||||
final TestGesture dragEndThumb = await tester.startGesture(bottomThumbLocation);
|
||||
await tester.pump(kPressTimeout);
|
||||
await dragEndThumb.moveBy(const Offset(20.0, 0));
|
||||
await tester.pump(kPressTimeout);
|
||||
await dragEndThumb.moveBy(const Offset(-20.0, 0));
|
||||
await dragEndThumb.up();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Verify overlay disappears.
|
||||
expect(
|
||||
Material.of(tester.element(find.byType(RangeSlider))),
|
||||
isNot(paints..circle(color: dragColor)),
|
||||
);
|
||||
|
||||
// Hover on start thumb.
|
||||
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
|
||||
await gesture.addPointer();
|
||||
await gesture.moveTo(topThumbLocation);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Verify overlay appears only for start thumb and no shadow is visible.
|
||||
expect(
|
||||
Material.of(tester.element(find.byType(RangeSlider))),
|
||||
paints
|
||||
..circle(color: hoverColor)
|
||||
..path(color: Colors.black, style: PaintingStyle.stroke, strokeWidth: 2.0)
|
||||
..path(color: Colors.black, style: PaintingStyle.stroke, strokeWidth: 2.0),
|
||||
);
|
||||
|
||||
final RenderObject renderObject = tester.renderObject(find.byType(RangeSlider));
|
||||
// 2 thumbs and 1 overlay.
|
||||
expect(renderObject, paintsExactlyCountTimes(#drawCircle, 3));
|
||||
|
||||
// Move away from thumb
|
||||
await gesture.moveTo(tester.getTopRight(find.byType(RangeSlider)));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Verify overlay disappears
|
||||
expect(
|
||||
Material.of(tester.element(find.byType(RangeSlider))),
|
||||
isNot(paints..circle(color: hoverColor)),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user