private void fling() {
    updatePosition();

    stopAnimationTimer();

    boolean stopped = stopped();
    mX.startFling(stopped);
    mY.startFling(stopped);

    startAnimationTimer(new FlingRunnable());
  }
  /* Performs a bounce-back animation to the given viewport metrics. */
  private void bounce(ImmutableViewportMetrics metrics) {
    stopAnimationTimer();

    ImmutableViewportMetrics bounceStartMetrics = getMetrics();
    if (bounceStartMetrics.fuzzyEquals(metrics)) {
      setState(PanZoomState.NOTHING);
      return;
    }

    // At this point we have already set mState to BOUNCE or ANIMATED_ZOOM, so
    // getRedrawHint() is returning false. This means we can safely call
    // setAnimationTarget to set the new final display port and not have it get
    // clobbered by display ports from intermediate animation frames.
    mTarget.setAnimationTarget(metrics);
    startAnimationTimer(new BounceRunnable(bounceStartMetrics, metrics));
  }