@Override
  protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    super.onLayout(changed, left, top, right, bottom);

    // Target placement width/height. This puts the targets on the greater of the ring
    // width or the specified outer radius.
    final float placementWidth = getRingWidth();
    final float placementHeight = getRingHeight();
    float newWaveCenterX = mHorizontalInset + (mMaxTargetWidth + placementWidth) / 2;
    float newWaveCenterY = mVerticalInset + (mMaxTargetHeight + placementHeight) / 2;

    if (mInitialLayout) {
      stopAndHideWaveAnimation();
      hideTargets(false, false);
      mInitialLayout = false;
    }

    mOuterRing.setPositionX(newWaveCenterX);
    mOuterRing.setPositionY(newWaveCenterY);

    mPointCloud.setScale(mRingScaleFactor);

    mHandleDrawable.setPositionX(newWaveCenterX);
    mHandleDrawable.setPositionY(newWaveCenterY);

    updateTargetPositions(newWaveCenterX, newWaveCenterY);
    updatePointCloudPosition(newWaveCenterX, newWaveCenterY);
    updateGlowPosition(newWaveCenterX, newWaveCenterY);

    mWaveCenterX = newWaveCenterX;
    mWaveCenterY = newWaveCenterY;

    if (DEBUG) dump();
  }
  private void internalSetTargetResources(int resourceId) {
    final ArrayList<TargetDrawable> targets = loadDrawableArray(resourceId);
    mTargetDrawables = targets;
    mTargetResourceId = resourceId;

    int maxWidth = mHandleDrawable.getWidth();
    int maxHeight = mHandleDrawable.getHeight();
    final int count = targets.size();
    for (int i = 0; i < count; i++) {
      TargetDrawable target = targets.get(i);
      maxWidth = Math.max(maxWidth, target.getWidth());
      maxHeight = Math.max(maxHeight, target.getHeight());
    }
    if (mMaxTargetWidth != maxWidth || mMaxTargetHeight != maxHeight) {
      mMaxTargetWidth = maxWidth;
      mMaxTargetHeight = maxHeight;
      requestLayout(); // required to resize layout and call updateTargetPositions()
    } else {
      updateTargetPositions(mWaveCenterX, mWaveCenterY);
      updatePointCloudPosition(mWaveCenterX, mWaveCenterY);
    }
  }