Skip to content

Commit 87cb150

Browse files
authored
InkResponse highlights can be updated (#115635)
Co-authored-by: Bruno Leroux <[email protected]>
1 parent 18c8727 commit 87cb150

File tree

2 files changed

+206
-0
lines changed

2 files changed

+206
-0
lines changed

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

+15
Original file line numberDiff line numberDiff line change
@@ -834,6 +834,21 @@ class _InkResponseState extends State<_InkResponseStateWidget>
834834
}
835835
initStatesController();
836836
}
837+
if (widget.customBorder != oldWidget.customBorder ||
838+
widget.radius != oldWidget.radius ||
839+
widget.borderRadius != oldWidget.borderRadius ||
840+
widget.highlightShape != oldWidget.highlightShape) {
841+
final InkHighlight? hoverHighLight = _highlights[_HighlightType.hover];
842+
if (hoverHighLight != null) {
843+
hoverHighLight.dispose();
844+
updateHighlight(_HighlightType.hover, value: _hovering, callOnHover: false);
845+
}
846+
final InkHighlight? focusHighLight = _highlights[_HighlightType.focus];
847+
if (focusHighLight != null) {
848+
focusHighLight.dispose();
849+
// Do not call updateFocusHighlights() here because it is called below
850+
}
851+
}
837852
if (enabled != isWidgetEnabled(oldWidget)) {
838853
statesController.update(MaterialState.disabled, !enabled);
839854
if (!enabled) {

packages/flutter/test/material/ink_well_test.dart

+191
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,197 @@ void main() {
445445
expect(inkFeatures, paints..circle(radius: 20, color: const Color(0xff0000ff)));
446446
});
447447

448+
testWidgets('InkResponse radius can be updated', (WidgetTester tester) async {
449+
FocusManager.instance.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
450+
final FocusNode focusNode = FocusNode(debugLabel: 'Ink Focus');
451+
Widget boilerplate(double radius) {
452+
return Material(
453+
child: Directionality(
454+
textDirection: TextDirection.ltr,
455+
child: Center(
456+
child: SizedBox(
457+
width: 100,
458+
height: 100,
459+
child: InkResponse(
460+
focusNode: focusNode,
461+
radius: radius,
462+
focusColor: const Color(0xff0000ff),
463+
onTap: () { },
464+
),
465+
),
466+
),
467+
),
468+
);
469+
}
470+
await tester.pumpWidget(boilerplate(10));
471+
await tester.pumpAndSettle();
472+
final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
473+
expect(inkFeatures, paintsExactlyCountTimes(#drawCircle, 0));
474+
475+
focusNode.requestFocus();
476+
await tester.pumpAndSettle();
477+
expect(inkFeatures, paintsExactlyCountTimes(#drawCircle, 1));
478+
expect(inkFeatures, paints..circle(radius: 10, color: const Color(0xff0000ff)));
479+
480+
await tester.pumpWidget(boilerplate(20));
481+
await tester.pumpAndSettle();
482+
expect(inkFeatures, paintsExactlyCountTimes(#drawCircle, 1));
483+
expect(inkFeatures, paints..circle(radius: 20, color: const Color(0xff0000ff)));
484+
});
485+
486+
testWidgets('InkResponse highlightShape can be updated', (WidgetTester tester) async {
487+
FocusManager.instance.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
488+
final FocusNode focusNode = FocusNode(debugLabel: 'Ink Focus');
489+
Widget boilerplate(BoxShape shape) {
490+
return Material(
491+
child: Directionality(
492+
textDirection: TextDirection.ltr,
493+
child: Center(
494+
child: SizedBox(
495+
width: 100,
496+
height: 100,
497+
child: InkResponse(
498+
focusNode: focusNode,
499+
highlightShape: shape,
500+
borderRadius: BorderRadius.circular(10),
501+
focusColor: const Color(0xff0000ff),
502+
onTap: () { },
503+
),
504+
),
505+
),
506+
),
507+
);
508+
}
509+
510+
await tester.pumpWidget(boilerplate(BoxShape.circle));
511+
await tester.pumpAndSettle();
512+
final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
513+
expect(inkFeatures, paintsExactlyCountTimes(#drawCircle, 0));
514+
expect(inkFeatures, paintsExactlyCountTimes(#drawRRect, 0));
515+
516+
focusNode.requestFocus();
517+
await tester.pumpAndSettle();
518+
expect(inkFeatures, paintsExactlyCountTimes(#drawCircle, 1));
519+
expect(inkFeatures, paintsExactlyCountTimes(#drawRRect, 0));
520+
521+
await tester.pumpWidget(boilerplate(BoxShape.rectangle));
522+
await tester.pumpAndSettle();
523+
expect(inkFeatures, paintsExactlyCountTimes(#drawCircle, 0));
524+
expect(inkFeatures, paintsExactlyCountTimes(#drawRRect, 1));
525+
});
526+
527+
testWidgets('InkWell borderRadius can be updated', (WidgetTester tester) async {
528+
FocusManager.instance.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
529+
final FocusNode focusNode = FocusNode(debugLabel: 'Ink Focus');
530+
Widget boilerplate(BorderRadius borderRadius) {
531+
return Material(
532+
child: Directionality(
533+
textDirection: TextDirection.ltr,
534+
child: Center(
535+
child: SizedBox(
536+
width: 100,
537+
height: 100,
538+
child: InkWell(
539+
focusNode: focusNode,
540+
borderRadius: borderRadius,
541+
focusColor: const Color(0xff0000ff),
542+
onTap: () { },
543+
),
544+
),
545+
),
546+
),
547+
);
548+
}
549+
550+
await tester.pumpWidget(boilerplate(BorderRadius.circular(10)));
551+
await tester.pumpAndSettle();
552+
final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
553+
expect(inkFeatures, paintsExactlyCountTimes(#drawRRect, 0));
554+
555+
focusNode.requestFocus();
556+
await tester.pumpAndSettle();
557+
expect(inkFeatures, paintsExactlyCountTimes(#drawRRect, 1));
558+
expect(inkFeatures, paints..rrect(
559+
rrect: RRect.fromLTRBR(350.0, 250.0, 450.0, 350.0, const Radius.circular(10)),
560+
color: const Color(0xff0000ff),
561+
));
562+
563+
await tester.pumpWidget(boilerplate(BorderRadius.circular(30)));
564+
await tester.pumpAndSettle();
565+
expect(inkFeatures, paintsExactlyCountTimes(#drawRRect, 1));
566+
expect(inkFeatures, paints..rrect(
567+
rrect: RRect.fromLTRBR(350.0, 250.0, 450.0, 350.0, const Radius.circular(30)),
568+
color: const Color(0xff0000ff),
569+
));
570+
});
571+
572+
testWidgets('InkWell customBorder can be updated', (WidgetTester tester) async {
573+
FocusManager.instance.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
574+
final FocusNode focusNode = FocusNode(debugLabel: 'Ink Focus');
575+
Widget boilerplate(BorderRadius borderRadius) {
576+
return Material(
577+
child: Directionality(
578+
textDirection: TextDirection.ltr,
579+
child: Align(
580+
alignment: Alignment.topLeft,
581+
child: SizedBox(
582+
width: 100,
583+
height: 100,
584+
child: MouseRegion(
585+
child: InkWell(
586+
focusNode: focusNode,
587+
customBorder: RoundedRectangleBorder(borderRadius: borderRadius),
588+
hoverColor: const Color(0xff00ff00),
589+
onTap: () { },
590+
),
591+
),
592+
),
593+
),
594+
),
595+
);
596+
}
597+
598+
await tester.pumpWidget(boilerplate(BorderRadius.circular(20)));
599+
await tester.pumpAndSettle();
600+
final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
601+
expect(inkFeatures, paintsExactlyCountTimes(#clipPath, 0));
602+
603+
focusNode.requestFocus();
604+
await tester.pumpAndSettle();
605+
expect(inkFeatures, paintsExactlyCountTimes(#clipPath, 1));
606+
607+
const Rect expectedClipRect = Rect.fromLTRB(0, 0, 100, 100);
608+
Path expectedClipPath = Path()
609+
..addRRect(RRect.fromRectAndRadius(
610+
expectedClipRect,
611+
const Radius.circular(20),
612+
));
613+
expect(
614+
inkFeatures,
615+
paints..clipPath(pathMatcher: coversSameAreaAs(
616+
expectedClipPath,
617+
areaToCompare: expectedClipRect.inflate(20.0),
618+
sampleSize: 100,
619+
)),
620+
);
621+
622+
await tester.pumpWidget(boilerplate(BorderRadius.circular(40)));
623+
await tester.pumpAndSettle();
624+
expectedClipPath = Path()
625+
..addRRect(RRect.fromRectAndRadius(
626+
expectedClipRect,
627+
const Radius.circular(40),
628+
));
629+
expect(
630+
inkFeatures,
631+
paints..clipPath(pathMatcher: coversSameAreaAs(
632+
expectedClipPath,
633+
areaToCompare: expectedClipRect.inflate(20.0),
634+
sampleSize: 100,
635+
)),
636+
);
637+
});
638+
448639
testWidgets("ink response doesn't change color on focus when on touch device", (WidgetTester tester) async {
449640
FocusManager.instance.highlightStrategy = FocusHighlightStrategy.alwaysTouch;
450641
final FocusNode focusNode = FocusNode(debugLabel: 'Ink Focus');

0 commit comments

Comments
 (0)