/** Ensures correct size of the widget. */ @Override protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width = 200; if (MeasureSpec.UNSPECIFIED != MeasureSpec.getMode(widthMeasureSpec)) { width = MeasureSpec.getSize(widthMeasureSpec); } int height = thumbImage.getHeight() + (!mShowTextAboveThumbs ? 0 : PixelUtil.dpToPx(getContext(), HEIGHT_IN_DP)); if (MeasureSpec.UNSPECIFIED != MeasureSpec.getMode(heightMeasureSpec)) { height = Math.min(height, MeasureSpec.getSize(heightMeasureSpec)); } setMeasuredDimension(width, height); }
/** Draws the widget on the given canvas. */ @Override protected synchronized void onDraw(@NonNull Canvas canvas) { super.onDraw(canvas); paint.setTextSize(mTextSize); paint.setStyle(Style.FILL); paint.setColor(mDefaultColor); paint.setAntiAlias(true); float minMaxLabelSize = 0; if (mShowLabels) { // draw min and max labels String minLabel = getContext().getString(R.string.demo_min_label); String maxLabel = getContext().getString(R.string.demo_max_label); minMaxLabelSize = Math.max(paint.measureText(minLabel), paint.measureText(maxLabel)); float minMaxHeight = mTextOffset + mThumbHalfHeight + mTextSize / 3; canvas.drawText(minLabel, 0, minMaxHeight, paint); canvas.drawText(maxLabel, getWidth() - minMaxLabelSize, minMaxHeight, paint); } padding = mInternalPad + minMaxLabelSize + mThumbHalfWidth; // draw seek bar background line mRect.left = padding; mRect.right = getWidth() - padding; canvas.drawRoundRect(mRect, mRoundedCorners, mRoundedCorners, paint); boolean selectedValuesAreDefault = (getSelectedMinValue().equals(getAbsoluteMinValue()) && getSelectedMaxValue().equals(getAbsoluteMaxValue())); int colorToUseForButtonsAndHighlightedLine = !mAlwaysActive && selectedValuesAreDefault ? mDefaultColor : // default values mActiveColor; // non default, filter is active // draw seek bar active range line mRect.left = normalizedToScreen(normalizedMinValue); mRect.right = normalizedToScreen(normalizedMaxValue); paint.setColor(colorToUseForButtonsAndHighlightedLine); canvas.drawRoundRect(mRect, mRoundedCorners, mRoundedCorners, paint); // draw minimum thumb if not a single thumb control if (!mSingleThumb) { drawThumb( normalizedToScreen(normalizedMinValue), Thumb.MIN.equals(pressedThumb), canvas, selectedValuesAreDefault); } // draw maximum thumb drawThumb( normalizedToScreen(normalizedMaxValue), Thumb.MAX.equals(pressedThumb), canvas, selectedValuesAreDefault); // draw the text if sliders have moved from default edges if (mShowTextAboveThumbs) { paint.setTextSize(mTextSize); paint.setColor(mTextAboveThumbsColor); // give text a bit more space here so it doesn't get cut off int offset = PixelUtil.dpToPx(getContext(), TEXT_LATERAL_PADDING_IN_DP); String minText = String.valueOf(getSelectedMinValue()); String maxText = String.valueOf(getSelectedMaxValue()); if (mValueProcessor != null) { minText = mValueProcessor.getProcessedValue(getSelectedMinValue()); maxText = mValueProcessor.getProcessedValue(getSelectedMaxValue()); } float minTextWidth = paint.measureText(minText) + offset; float maxTextWidth = paint.measureText(maxText) + offset; if (!mSingleThumb) { canvas.drawText( minText, normalizedToScreen(normalizedMinValue) - minTextWidth * 0.5f, mDistanceToTop + mTextSize, paint); } canvas.drawText( maxText, normalizedToScreen(normalizedMaxValue) - maxTextWidth * 0.5f, mDistanceToTop + mTextSize, paint); } }
private void init(Context context, AttributeSet attrs) { float barHeight; int thumbNormal = R.drawable.seek_thumb_normal; int thumbPressed = R.drawable.seek_thumb_pressed; int thumbDisabled = R.drawable.seek_thumb_disabled; if (attrs == null) { setRangeToDefaultValues(); mInternalPad = PixelUtil.dpToPx(context, INITIAL_PADDING_IN_DP); barHeight = PixelUtil.dpToPx(context, LINE_HEIGHT_IN_DP); mActiveColor = ACTIVE_COLOR; mDefaultColor = Color.GRAY; mTextAboveThumbsColor = Color.WHITE; mAlwaysActive = false; mShowTextAboveThumbs = true; } else { TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.RangeSeekBar, 0, 0); try { setRangeValues( extractNumericValueFromAttributes( a, R.styleable.RangeSeekBar_absoluteMinValue, DEFAULT_MINIMUM), extractNumericValueFromAttributes( a, R.styleable.RangeSeekBar_absoluteMaxValue, DEFAULT_MAXIMUM)); mShowTextAboveThumbs = a.getBoolean(R.styleable.RangeSeekBar_valuesAboveThumbs, true); mSingleThumb = a.getBoolean(R.styleable.RangeSeekBar_singleThumb, false); mShowLabels = a.getBoolean(R.styleable.RangeSeekBar_showLabels, true); mInternalPad = a.getDimensionPixelSize( R.styleable.RangeSeekBar_internalPadding, INITIAL_PADDING_IN_DP); barHeight = a.getDimensionPixelSize(R.styleable.RangeSeekBar_barHeight, LINE_HEIGHT_IN_DP); mRoundedCorners = a.getDimensionPixelSize(R.styleable.RangeSeekBar_roundedCorners, 0); mActiveColor = a.getColor(R.styleable.RangeSeekBar_activeColor, ACTIVE_COLOR); mDefaultColor = a.getColor(R.styleable.RangeSeekBar_defaultColor, Color.GRAY); mTextAboveThumbsColor = a.getColor(R.styleable.RangeSeekBar_textAboveThumbsColor, Color.WHITE); mAlwaysActive = a.getBoolean(R.styleable.RangeSeekBar_alwaysActive, false); Drawable normalDrawable = a.getDrawable(R.styleable.RangeSeekBar_thumbNormal); if (normalDrawable != null) { thumbImage = BitmapUtil.drawableToBitmap(normalDrawable); } Drawable disabledDrawable = a.getDrawable(R.styleable.RangeSeekBar_thumbDisabled); if (disabledDrawable != null) { thumbDisabledImage = BitmapUtil.drawableToBitmap(disabledDrawable); } Drawable pressedDrawable = a.getDrawable(R.styleable.RangeSeekBar_thumbPressed); if (pressedDrawable != null) { thumbPressedImage = BitmapUtil.drawableToBitmap(pressedDrawable); } } finally { a.recycle(); } } if (thumbImage == null) { thumbImage = BitmapFactory.decodeResource(getResources(), thumbNormal); } if (thumbPressedImage == null) { thumbPressedImage = BitmapFactory.decodeResource(getResources(), thumbPressed); } if (thumbDisabledImage == null) { thumbDisabledImage = BitmapFactory.decodeResource(getResources(), thumbDisabled); } mThumbHalfWidth = 0.5f * thumbImage.getWidth(); mThumbHalfHeight = 0.5f * thumbImage.getHeight(); setValuePrimAndNumberType(); mTextSize = PixelUtil.dpToPx(context, DEFAULT_TEXT_SIZE_IN_DP); mDistanceToTop = PixelUtil.dpToPx(context, DEFAULT_TEXT_DISTANCE_TO_TOP_IN_DP); mTextOffset = !mShowTextAboveThumbs ? 0 : this.mTextSize + PixelUtil.dpToPx(context, DEFAULT_TEXT_DISTANCE_TO_BUTTON_IN_DP) + this.mDistanceToTop; mRect = new RectF( padding, mTextOffset + mThumbHalfHeight - barHeight / 2, getWidth() - padding, mTextOffset + mThumbHalfHeight + barHeight / 2); // make RangeSeekBar focusable. This solves focus handling issues in case EditText widgets are // being used along with the RangeSeekBar within ScrollViews. setFocusable(true); setFocusableInTouchMode(true); mScaledTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); mValueProcessor = new RangeSeekBarValueProcessor(); }