/** Set either the hour or the minute. Will set the internal value, and set the selection. */ private void setItem(int index, int value) { if (index == HOUR_INDEX) { setValueForItem(HOUR_INDEX, value); int hourDegrees = (value % 12) * HOUR_VALUE_TO_DEGREES_STEP_SIZE; mHourRadialSelectorView.setSelection(hourDegrees, isHourInnerCircle(value), false); mHourRadialSelectorView.invalidate(); } else if (index == MINUTE_INDEX) { setValueForItem(MINUTE_INDEX, value); int minuteDegrees = value * MINUTE_VALUE_TO_DEGREES_STEP_SIZE; mMinuteRadialSelectorView.setSelection(minuteDegrees, false, false); mMinuteRadialSelectorView.invalidate(); } }
/** * Initialize this selector with the state of the picker. * * @param context Current context. * @param is24HourMode Whether the selector is in 24-hour mode, which will tell us whether the * circle's center is moved up slightly to make room for the AM/PM circles. * @param hasInnerCircle Whether we have both an inner and an outer circle of numbers that may be * selected. Should be true for 24-hour mode in the hours circle. * @param disappearsOut Whether the numbers' animation will have them disappearing out or * disappearing in. * @param selectionDegrees The initial degrees to be selected. * @param isInnerCircle Whether the initial selection is in the inner or outer circle. Will be * ignored when hasInnerCircle is false. */ public void initialize( Context context, boolean is24HourMode, boolean hasInnerCircle, boolean disappearsOut, int selectionDegrees, boolean isInnerCircle, boolean dark) { if (this.mIsInitialized) { Log.e(TAG, "This RadialSelectorView may only be initialized once."); return; } Resources res = context.getResources(); int selectorColor = res.getColor(dark ? R.color.Red : R.color.blue); this.mPaint.setColor(selectorColor); this.mPaint.setAntiAlias(true); // Calculate values for the circle radius size. this.mIs24HourMode = is24HourMode; if (is24HourMode) { this.mCircleRadiusMultiplier = Float.parseFloat(res.getString(R.string.circle_radius_multiplier_24HourMode)); } else { this.mCircleRadiusMultiplier = Float.parseFloat(res.getString(R.string.circle_radius_multiplier)); this.mAmPmCircleRadiusMultiplier = Float.parseFloat(res.getString(R.string.ampm_circle_radius_multiplier)); } // Calculate values for the radius size(s) of the numbers circle(s). this.mHasInnerCircle = hasInnerCircle; if (hasInnerCircle) { this.mInnerNumbersRadiusMultiplier = Float.parseFloat(res.getString(R.string.numbers_radius_multiplier_inner)); this.mOuterNumbersRadiusMultiplier = Float.parseFloat(res.getString(R.string.numbers_radius_multiplier_outer)); } else { this.mNumbersRadiusMultiplier = Float.parseFloat(res.getString(R.string.numbers_radius_multiplier_normal)); } this.mSelectionRadiusMultiplier = Float.parseFloat(res.getString(R.string.selection_radius_multiplier)); // Calculate values for the transition mid-way states. this.mAnimationRadiusMultiplier = 1; this.mTransitionMidRadiusMultiplier = 1f + 0.05f * (disappearsOut ? -1 : 1); this.mTransitionEndRadiusMultiplier = 1f + 0.3f * (disappearsOut ? 1 : -1); this.mInvalidateUpdateListener = new InvalidateUpdateListener(); setSelection(selectionDegrees, isInnerCircle, false); this.mIsInitialized = true; this.mDark = dark; }
/** * For the currently showing view (either hours or minutes), re-calculate the position for the * selector, and redraw it at that position. The input degrees will be snapped to a selectable * value. * * @param degrees Degrees which should be selected. * @param isInnerCircle Whether the selection should be in the inner circle; will be ignored if * there is no inner circle. * @param forceToVisibleValue Even if the currently-showing circle allows for fine-grained * selection (i.e. minutes), force the selection to one of the visibly-showing values. * @param forceDrawDot The dot in the circle will generally only be shown when the selection is on * non-visible values, but use this to force the dot to be shown. * @return The value that was selected, i.e. 0-23 for hours, 0-59 for minutes. */ private int reselectSelector( int degrees, boolean isInnerCircle, boolean forceToVisibleValue, boolean forceDrawDot) { if (degrees == -1) { return -1; } int currentShowing = getCurrentItemShowing(); int stepSize; boolean allowFineGrained = !forceToVisibleValue && (currentShowing == MINUTE_INDEX); if (allowFineGrained) { degrees = snapPrefer30s(degrees); } else { degrees = snapOnly30s(degrees, 0); } RadialSelectorView radialSelectorView; if (currentShowing == HOUR_INDEX) { radialSelectorView = mHourRadialSelectorView; stepSize = HOUR_VALUE_TO_DEGREES_STEP_SIZE; } else { radialSelectorView = mMinuteRadialSelectorView; stepSize = MINUTE_VALUE_TO_DEGREES_STEP_SIZE; } radialSelectorView.setSelection(degrees, isInnerCircle, forceDrawDot); radialSelectorView.invalidate(); if (currentShowing == HOUR_INDEX) { if (mIs24HourMode) { if (degrees == 0 && isInnerCircle) { degrees = 360; } else if (degrees == 360 && !isInnerCircle) { degrees = 0; } } else if (degrees == 0) { degrees = 360; } } else if (degrees == 360 && currentShowing == MINUTE_INDEX) { degrees = 0; } int value = degrees / stepSize; if (currentShowing == HOUR_INDEX && mIs24HourMode && !isInnerCircle && degrees != 0) { value += 12; } return value; }