@Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { if (!mInitialized) return; if (mInAnimation) { rotateWheel(); mHandler.post(mRunnable); } mCenterX = right - left - Util.dpToPixel(IndicatorControlWheelContainer.FULL_WHEEL_RADIUS); mCenterY = (bottom - top) / 2; // Layout the indicators based on the current level. // The icons are spreaded on the left side of the shutter button. for (int i = 0; i < getChildCount(); ++i) { View view = getChildAt(i); // We still need to show the disabled indicators in the second level. double radian = mChildRadians[i]; double startVisibleRadians = mInAnimation ? mStartVisibleRadians[1] : mStartVisibleRadians[mCurrentLevel]; double endVisibleRadians = mInAnimation ? mEndVisibleRadians[1] : mEndVisibleRadians[mCurrentLevel]; if ((!view.isEnabled() && (mCurrentLevel == 0)) || (radian < (startVisibleRadians - HIGHLIGHT_RADIANS / 2)) || (radian > (endVisibleRadians + HIGHLIGHT_RADIANS / 2))) { view.setVisibility(View.GONE); continue; } view.setVisibility(View.VISIBLE); int x = mCenterX + (int) (mWheelRadius * Math.cos(radian)); int y = mCenterY - (int) (mWheelRadius * Math.sin(radian)); int width = view.getMeasuredWidth(); int height = view.getMeasuredHeight(); if (view == mZoomControl) { // ZoomControlWheel matches the size of its parent view. view.layout(0, 0, right - left, bottom - top); } else { view.layout(x - width / 2, y - height / 2, x + width / 2, y + height / 2); } } }