/// <summary> /// Ensures correct size of the widget. /// </summary> protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec) { var width = 200; if (MeasureSpecMode.Unspecified != MeasureSpec.GetMode(widthMeasureSpec)) { width = MeasureSpec.GetSize(widthMeasureSpec); } var height = ThumbImage.Height + (ShowTextAboveThumbs ? PixelUtil.DpToPx(Context, HeightInDp) + PixelUtil.SpToPx(Context, TextSizeInSp) : 0) + (ThumbShadow ? ThumbShadowYOffset + _thumbShadowBlur : 0); if (MeasureSpecMode.Unspecified != MeasureSpec.GetMode(heightMeasureSpec)) { height = Math.Min(height, MeasureSpec.GetSize(heightMeasureSpec)); } SetMeasuredDimension(width, height); }
/// <summary> /// Draws the widget on the given canvas. /// </summary> protected override void OnDraw(Canvas canvas) { base.OnDraw(canvas); _paint.TextSize = _textSize; _paint.SetStyle(Paint.Style.Fill); _paint.Color = DefaultColor; _paint.AntiAlias = true; float minMaxLabelSize = 0; if (ShowLabels) { // draw min and max labels var minLabel = Context.GetString(Resource.String.demo_min_label); var maxLabel = Context.GetString(Resource.String.demo_max_label); minMaxLabelSize = Math.Max(_paint.MeasureText(minLabel), _paint.MeasureText(maxLabel)); var minMaxHeight = _textOffset + _thumbHalfHeight + (float)_textSize / 3; if (!MinThumbTextHidden) { canvas.DrawText(minLabel, 0, minMaxHeight, _paint); } if (!MaxThumbTextHidden) { canvas.DrawText(maxLabel, Width - minMaxLabelSize, minMaxHeight, _paint); } } _padding = _internalPad + minMaxLabelSize + _thumbHalfWidth; // draw seek bar background line _rect.Left = _padding; _rect.Right = Width - _padding; _rect.Top = _textOffset + _thumbHalfHeight - _barHeight / 2; _rect.Bottom = _textOffset + _thumbHalfHeight + _barHeight / 2; canvas.DrawRect(_rect, _paint); var selectedValuesAreDefault = NormalizedMinValue <= MinDeltaForDefault && NormalizedMaxValue >= 1 - MinDeltaForDefault; var colorToUseForButtonsAndHighlightedLine = !Enabled || (!AlwaysActive && !ActivateOnDefaultValues && selectedValuesAreDefault) ? DefaultColor // default values : ActiveColor; // non default, filter is active // draw seek bar active range line _rect.Left = NormalizedToScreen(NormalizedMinValue); _rect.Right = NormalizedToScreen(NormalizedMaxValue); _paint.Color = colorToUseForButtonsAndHighlightedLine; canvas.DrawRect(_rect, _paint); // draw minimum thumb (& shadow if requested) if not a single thumb control if (!MinThumbHidden) { if (ThumbShadow) { DrawThumbShadow(NormalizedToScreen(NormalizedMinValue), canvas); } DrawThumb(NormalizedToScreen(NormalizedMinValue), Thumb.Lower.Equals(_pressedThumb), canvas, selectedValuesAreDefault); } // draw maximum thumb & shadow (if necessary) if (!MaxThumbHidden) { if (ThumbShadow) { DrawThumbShadow(NormalizedToScreen(NormalizedMaxValue), canvas); } DrawThumb(NormalizedToScreen(NormalizedMaxValue), Thumb.Upper.Equals(_pressedThumb), canvas, selectedValuesAreDefault); } // draw the text if sliders have moved from default edges if (!ShowTextAboveThumbs || (!ActivateOnDefaultValues && selectedValuesAreDefault)) { return; } _paint.TextSize = _textSize; _paint.Color = TextAboveThumbsColor; var minText = ValueToString(GetSelectedMinValue(), Thumb.Lower); var maxText = ValueToString(GetSelectedMaxValue(), Thumb.Upper); var minTextWidth = _paint.MeasureText(minText); var maxTextWidth = _paint.MeasureText(maxText); // keep the position so that the labels don't get cut off var minPosition = Math.Max(0f, NormalizedToScreen(NormalizedMinValue) - minTextWidth * 0.5f); var maxPosition = Math.Min(Width - maxTextWidth, NormalizedToScreen(NormalizedMaxValue) - maxTextWidth * 0.5f); if (!MaxThumbHidden && !MinThumbHidden) { // check if the labels overlap, or are too close to each other var spacing = PixelUtil.DpToPx(Context, TextLateralPaddingInDp); var overlap = minPosition + minTextWidth - maxPosition + spacing; if (overlap > 0f) { // we could move them the same ("overlap * 0.5f") // but we rather move more the one which is farther from the ends, as it has more space minPosition -= overlap * NormalizedMinValue / (NormalizedMinValue + 1 - NormalizedMaxValue); maxPosition += overlap * (1 - NormalizedMaxValue) / (NormalizedMinValue + 1 - NormalizedMaxValue); } } if (!MinThumbHidden && !MinThumbTextHidden) { canvas.DrawText(minText, minPosition, _distanceToTop + _textSize, _paint); } if (!MaxThumbHidden && !MaxThumbTextHidden) { canvas.DrawText(maxText, maxPosition, _distanceToTop + _textSize, _paint); } }
private void Init(Context context, IAttributeSet attrs) { var defaultShadowColor = Color.Argb(75, 0, 0, 0); var defaultShadowYOffset = PixelUtil.DpToPx(context, 2); var defaultShadowXOffset = PixelUtil.DpToPx(context, 0); var defaultShadowBlur = PixelUtil.DpToPx(context, 2); _distanceToTop = PixelUtil.DpToPx(context, DefaultTextDistanceToTopInDp); if (attrs == null) { SetRangeToDefaultValues(); _internalPad = PixelUtil.DpToPx(context, InitialPaddingInDp); _barHeight = PixelUtil.DpToPx(context, LineHeightInDp); ActiveColor = DefaultDarkBlueColor; DefaultColor = Color.Gray; AlwaysActive = false; ShowTextAboveThumbs = true; TextAboveThumbsColor = Color.White; thumbShadowColor = defaultShadowColor; ThumbShadowXOffset = defaultShadowXOffset; ThumbShadowYOffset = defaultShadowYOffset; _thumbShadowBlur = defaultShadowBlur; ActivateOnDefaultValues = false; TextSizeInSp = DefaultTextSizeInSp; MaterialUI = false; } else { var a = Context.ObtainStyledAttributes(attrs, Resource.Styleable.RangeSliderControl, 0, 0); try { SetRangeValues(ExtractNumericValueFromAttributes(a, Resource.Styleable.RangeSliderControl_absoluteMinValue, DefaultMinimum), ExtractNumericValueFromAttributes(a, Resource.Styleable.RangeSliderControl_absoluteMaxValue, DefaultMaximum)); ShowTextAboveThumbs = a.GetBoolean(Resource.Styleable.RangeSliderControl_valuesAboveThumbs, true); TextAboveThumbsColor = a.GetColor(Resource.Styleable.RangeSliderControl_textAboveThumbsColor, Color.White); MinThumbHidden = a.GetBoolean(Resource.Styleable.RangeSliderControl_minThumbHidden, false); MaxThumbHidden = a.GetBoolean(Resource.Styleable.RangeSliderControl_maxThumbHidden, false); ShowLabels = a.GetBoolean(Resource.Styleable.RangeSliderControl_showRangeLabels, true); _internalPad = a.GetDimensionPixelSize(Resource.Styleable.RangeSliderControl_internalPadding, InitialPaddingInDp); _barHeight = a.GetDimensionPixelSize(Resource.Styleable.RangeSliderControl_barHeight, LineHeightInDp); ActiveColor = a.GetColor(Resource.Styleable.RangeSliderControl_activeColor, DefaultDarkBlueColor); DefaultColor = a.GetColor(Resource.Styleable.RangeSliderControl_defaultColor, Color.Gray); AlwaysActive = a.GetBoolean(Resource.Styleable.RangeSliderControl_alwaysActive, false); StepValue = ExtractNumericValueFromAttributes(a, Resource.Styleable.RangeSliderControl_stepValue, DefaultStepValue); StepValueContinuously = a.GetBoolean(Resource.Styleable.RangeSliderControl_stepValueContinuously, false); var normalDrawable = a.GetDrawable(Resource.Styleable.RangeSliderControl_thumbNormal); if (normalDrawable != null) { DefaultThumbImage = BitmapUtil.DrawableToBitmap(normalDrawable); } var disabledDrawable = a.GetDrawable(Resource.Styleable.RangeSliderControl_thumbDisabled); if (disabledDrawable != null) { DefaultThumbDisabledImage = BitmapUtil.DrawableToBitmap(disabledDrawable); } var pressedDrawable = a.GetDrawable(Resource.Styleable.RangeSliderControl_thumbPressed); if (pressedDrawable != null) { DefaultThumbPressedImage = BitmapUtil.DrawableToBitmap(pressedDrawable); } ThumbShadow = a.GetBoolean(Resource.Styleable.RangeSliderControl_thumbShadow, false); thumbShadowColor = a.GetColor(Resource.Styleable.RangeSliderControl_thumbShadowColor, defaultShadowColor); ThumbShadowXOffset = a.GetDimensionPixelSize(Resource.Styleable.RangeSliderControl_thumbShadowXOffset, defaultShadowXOffset); ThumbShadowYOffset = a.GetDimensionPixelSize(Resource.Styleable.RangeSliderControl_thumbShadowYOffset, defaultShadowYOffset); _thumbShadowBlur = a.GetDimensionPixelSize(Resource.Styleable.RangeSliderControl_thumbShadowBlur, defaultShadowBlur); ActivateOnDefaultValues = a.GetBoolean(Resource.Styleable.RangeSliderControl_activateOnDefaultValues, false); TextSizeInSp = a.GetInt(Resource.Styleable.RangeSliderControl_textSize, DefaultTextSizeInSp); MaterialUI = a.GetBoolean(Resource.Styleable.RangeSliderControl_materialUI, false); } finally { a.Recycle(); } } SetBarHeight(_barHeight); // make RangeSliderControl focusable. This solves focus handling issues in case EditText widgets are being used along with the RangeSliderControl within ScrollViews. Focusable = true; FocusableInTouchMode = true; _scaledTouchSlop = ViewConfiguration.Get(Context).ScaledTouchSlop; UpdateThumbImages(); }
private void UpdateTextOffset() { _textOffset = _showTextAboveThumbs ? _textSize + PixelUtil.DpToPx(Context, DefaultTextDistanceToButtonInDp) + _distanceToTop : 0; }