InkResponse class

An area of a Material that responds to touch. Has a configurable shape and can be configured to clip splashes that extend outside its bounds or not.

For a variant of this widget that is specialized for rectangular areas that always clip splashes, see InkWell.

An InkResponse widget does two things when responding to a tap:

  • It starts to animate a highlight. The shape of the highlight is determined by highlightShape. If it is a, the default, then the highlight is a circle of fixed size centered in the InkResponse. If it is BoxShape.rectangle, then the highlight is a box the size of the InkResponse itself, unless getRectCallback is provided, in which case that callback defines the rectangle. The color of the highlight is set by highlightColor.

  • Simultaneously, it starts to animate a splash. This is a growing circle initially centered on the tap location. If this is a containedInkWell, the splash grows to the radius while remaining centered at the tap location. Otherwise, the splash migrates to the center of the box as it grows.

The following two diagrams show how InkResponse looks when tapped if the highlightShape is (the default) and containedInkWell is false (also the default).

The first diagram shows how it looks if the InkResponse is relatively large:

The highlight is a disc centered in the box, smaller than the child widget.

The second diagram shows how it looks if the InkResponse is small:

The highlight is a disc overflowing the box, centered on the child.

The main thing to notice from these diagrams is that the splashes happily exceed the bounds of the widget (because containedInkWell is false).

The following diagram shows the effect when the InkResponse has a highlightShape of BoxShape.rectangle with containedInkWell set to true. These are the values used by InkWell.

The highlight is a rectangle the size of the box.

The InkResponse widget must have a Material widget as an ancestor. The Material widget is where the ink reactions are actually painted. This matches the material design premise wherein the Material is what is actually reacting to touches by spreading ink.

If a Widget uses this class directly, it should include the following line at the top of its build function to call debugCheckHasMaterial:



The ink splashes aren't visible!

If there is an opaque graphic, e.g. painted using a Container, Image, or DecoratedBox, between the Material widget and the InkResponse widget, then the splash won't be visible because it will be under the opaque graphic. This is because ink splashes draw on the underlying Material itself, as if the ink was spreading inside the material.

The Ink widget can be used as a replacement for Image, Container, or DecoratedBox to ensure that the image or decoration also paints in the Material itself, below the ink.

If this is not possible for some reason, e.g. because you are using an opaque CustomPaint widget, alternatively consider using a second Material above the opaque widget but below the InkResponse (as an ancestor to the ink response). The MaterialType.transparency material kind can be used for this purpose.

See also:

Implemented by


InkResponse({Key key, Widget child, GestureTapCallback onTap, GestureTapDownCallback onTapDown, GestureTapCallback onTapCancel, GestureTapCallback onDoubleTap, GestureLongPressCallback onLongPress, ValueChanged<bool> onHighlightChanged, bool containedInkWell: false, BoxShape highlightShape:, double radius, BorderRadius borderRadius, Color highlightColor, Color splashColor, InteractiveInkFeatureFactory splashFactory, bool enableFeedback: true, bool excludeFromSemantics: false })
Creates an area of a Material that responds to touch. [...]


borderRadius BorderRadius
The clipping radius of the containing rect. [...]
child Widget
The widget below this widget in the tree. [...]
containedInkWell bool
Whether this ink response should be clipped its bounds. [...]
enableFeedback bool
Whether detected gestures should provide acoustic and/or haptic feedback. [...]
excludeFromSemantics bool
Whether to exclude the gestures introduced by this widget from the semantics tree. [...]
highlightColor Color
The highlight color of the ink response. If this property is null then the highlight color of the theme, ThemeData.highlightColor, will be used. [...]
highlightShape BoxShape
The shape (e.g., circle, rectangle) to use for the highlight drawn around this part of the material. [...]
onDoubleTap GestureTapCallback
Called when the user double taps this part of the material.
onHighlightChanged ValueChanged<bool>
Called when this part of the material either becomes highlighted or stops being highlighted. [...]
onLongPress GestureLongPressCallback
Called when the user long-presses on this part of the material.
onTap GestureTapCallback
Called when the user taps this part of the material.
onTapCancel GestureTapCallback
Called when the user cancels a tap that was started on this part of the material.
onTapDown GestureTapDownCallback
Called when the user taps down this part of the material.
radius double
The radius of the ink splash. [...]
splashColor Color
The splash color of the ink response. If this property is null then the splash color of the theme, ThemeData.splashColor, will be used. [...]
splashFactory InteractiveInkFeatureFactory
Defines the appearance of the splash. [...]
hashCode int
The hash code for this object. [...]
read-only, inherited
key Key
Controls how one widget replaces another widget in the tree. [...]
final, inherited
runtimeType Type
A representation of the runtime type of the object.
read-only, inherited


createState() → _InkResponseState<InkResponse>
Creates the mutable state for this widget at a given location in the tree. [...]
debugCheckContext(BuildContext context) bool
Asserts that the given context satisfies the prerequisites for this class. [...]
debugFillProperties(DiagnosticPropertiesBuilder properties) → void
getRectCallback(RenderBox referenceBox) RectCallback
The rectangle to use for the highlight effect and for clipping the splash effects if containedInkWell is true. [...]
createElement() StatefulElement
Creates a StatefulElement to manage this widget's location in the tree. [...]
debugDescribeChildren() List<DiagnosticsNode>
Returns a list of DiagnosticsNode objects describing this node's children. [...]
@protected, inherited
noSuchMethod(Invocation invocation) → dynamic
Invoked when a non-existent method or property is accessed. [...]
toDiagnosticsNode({String name, DiagnosticsTreeStyle style }) DiagnosticsNode
Returns a debug representation of the object that is used by debugging tools and by toStringDeep. [...]
toString({DiagnosticLevel minLevel: DiagnosticLevel.debug }) String
Returns a string representation of this object.
toStringDeep({String prefixLineOne: '', String prefixOtherLines, DiagnosticLevel minLevel: DiagnosticLevel.debug }) String
Returns a string representation of this node and its descendants. [...]
toStringShallow({String joiner: ', ', DiagnosticLevel minLevel: DiagnosticLevel.debug }) String
Returns a one-line detailed description of the object. [...]
toStringShort() String
A short, textual description of this widget.


operator ==(dynamic other) bool
The equality operator. [...]