hitTest method

bool hitTest (HitTestResult result, { @required double mainAxisPosition, @required double crossAxisPosition })

Determines the set of render objects located at the given position.

Returns true if the given point is contained in this render object or one of its descendants. Adds any render objects that contain the point to the given hit test result.

The caller is responsible for providing the position in the local coordinate space of the callee. The callee is responsible for checking whether the given position is within its bounds.

Hit testing requires layout to be up-to-date but does not require painting to be up-to-date. That means a render object can rely upon performLayout having been called in hitTest but cannot rely upon paint having been called. For example, a render object might be a child of a RenderOpacity object, which calls hitTest on its children when its opacity is zero even through it does not paint its children.

Coordinates for RenderSliver objects

The mainAxisPosition is the distance in the AxisDirection (after applying the GrowthDirection) from the edge of the sliver's painted area. This can be an unusual direction, for example in the AxisDirection.up case this is a distance from the bottom of the sliver's painted area.

The crossAxisPosition is the distance in the other axis. If the cross axis is horizontal (i.e. the SliverConstraints.axisDirection is either AxisDirection.down or AxisDirection.up), then the crossAxisPosition is a distance from the left edge of the sliver. If the cross axis is vertical (i.e. the SliverConstraints.axisDirection is either AxisDirection.right or AxisDirection.left), then the crossAxisPosition is a distance from the top edge of the sliver.

Implementing hit testing for slivers

The most straight-forward way to implement hit testing for a new sliver render object is to override its hitTestSelf and hitTestChildren methods.

Implementation

bool hitTest(HitTestResult result, { @required double mainAxisPosition, @required double crossAxisPosition }) {
  if (mainAxisPosition >= 0.0 && mainAxisPosition < geometry.hitTestExtent &&
      crossAxisPosition >= 0.0 && crossAxisPosition < constraints.crossAxisExtent) {
    if (hitTestChildren(result, mainAxisPosition: mainAxisPosition, crossAxisPosition: crossAxisPosition) ||
        hitTestSelf(mainAxisPosition: mainAxisPosition, crossAxisPosition: crossAxisPosition)) {
      result.add(SliverHitTestEntry(
        this,
        mainAxisPosition: mainAxisPosition,
        crossAxisPosition: crossAxisPosition
      ));
      return true;
    }
  }
  return false;
}