Skip to content

Instantly share code, notes, and snippets.

@raghunandankavi2010
Created February 18, 2017 18:35
Show Gist options
  • Save raghunandankavi2010/1b06170fc1d556dd1d88ce17aafc37b1 to your computer and use it in GitHub Desktop.
Save raghunandankavi2010/1b06170fc1d556dd1d88ce17aafc37b1 to your computer and use it in GitHub Desktop.
Seekbar with touch move only on circle touch and not the highlight bar
package com.example.raghu.myapplication;
/**
* Created by Raghu on 18-02-2017.
*/
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import java.util.ArrayList;
/**
* Created by Raghu on 6/20/2016.
*/
public class CrystalSeekbar extends View {
//////////////////////////////////////////
// PRIVATE CONSTANTS
//////////////////////////////////////////
private static final int INVALID_POINTER_ID = 255;
//private static int DEFAULT_THUMB_WIDTH ;
//private static int DEFAULT_THUMB_HEIGHT;
private final float NO_STEP = -1f;
private int drawable;
public void setDrawable(int drawable) {
this.drawable = drawable;
}
public int getDrawable() {
return drawable;
}
private int textColor;
public CrystalSeekbar setTextColor(int textColor) {
this.textColor = textColor;
return this;
}
public int getTextColor() {
return textColor;
}
private int numberOfCircle;
public void setNumberOfCircle(int numberOfCircle) {
this.numberOfCircle = numberOfCircle;
}
public int getNumberOfCircle() {
return numberOfCircle;
}
//////////////////////////////////////////
// PUBLIC CONSTANTS CLASS
//////////////////////////////////////////
public static final class DataType {
public static final int LONG = 0;
public static final int DOUBLE = 1;
public static final int INTEGER = 2;
public static final int FLOAT = 3;
public static final int SHORT = 4;
public static final int BYTE = 5;
}
public static final class Position {
public static final int LEFT = 0;
public static final int RIGHT = 1;
}
private String[] text_draw ;
public void setText_draw(String[] text_draw) {
this.text_draw = text_draw;
}
public int getText_draw_color() {
return text_draw_color;
}
//////////////////////////////////////////
// PRIVATE VAR
//////////////////////////////////////////
private OnSeekbarChangeListener onSeekbarChangeListener;
private OnSeekbarFinalValueListener onSeekbarFinalValueListener;
private float absoluteMinValue;
private float absoluteMaxValue;
private float minValue;
private float maxValue;
private float minStartValue;
private float steps;
private int mActivePointerId = INVALID_POINTER_ID;
private int position;
private int nextPosition;
private int dataType;
private float cornerRadius;
private int barColor;
private int barHighlightColor;
private int leftThumbColor;
private int leftThumbColorNormal;
private int leftThumbColorPressed;
private float barPadding;
private float barHeight;
private float thumbWidth;
private float thumbHeight;
private float thumbDiameter;
private Drawable leftDrawable;
private Drawable leftDrawablePressed;
private Bitmap leftThumb;
private Bitmap leftThumbPressed;
private Thumb pressedThumb;
private double normalizedMinValue = 0d;
private double normalizedMaxValue = 100d;
private int pointerIndex;
private RectF _rect;
private Paint _paint, text_paint;
private RectF rectLeftThumb;
private boolean mIsDragging;
private int text_draw_color;
private Paint text_slider;
private Rect textBounds ;
private ArrayList<Integer> mCircle_Points_x = new ArrayList<>();
private float currentSlidingX;
private float radius_circle = 50;
private float circle_center_x;
private float circle_center_y;
//////////////////////////////////////////
// ENUMERATION
//////////////////////////////////////////
protected enum Thumb {MIN}
//////////////////////////////////////////
// CONSTRUCTOR
//////////////////////////////////////////
public CrystalSeekbar(Context context) {
this(context, null);
}
public CrystalSeekbar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CrystalSeekbar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// prevent render is in edit mode
if (isInEditMode()) return;
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CrystalRangeSeekbar);
try {
cornerRadius = getCornerRadius(array);
minValue = getMinValue(array);
maxValue = getMaxValue(array);
minStartValue = getMinStartValue(array);
steps = getSteps(array);
barColor = getBarColor(array);
barHighlightColor = getBarHighlightColor(array);
leftThumbColorNormal = getLeftThumbColor(array);
leftThumbColorPressed = getLeftThumbColorPressed(array);
leftDrawable = getLeftDrawable(array);
leftDrawablePressed = getLeftDrawablePressed(array);
dataType = getDataType(array);
position = getPosition(array);
nextPosition = position;
thumbDiameter = getDiameter(array);
text_draw_color = getTextToDrawColor(array);
} finally {
array.recycle();
}
init();
}
//////////////////////////////////////////
// INITIALIZING
//////////////////////////////////////////
protected void init() {
text_paint = new Paint();
text_paint.setColor(Color.BLACK);
text_paint.setTextSize(40);
text_paint.setStrokeWidth(40);
text_paint.setFlags(Paint.ANTI_ALIAS_FLAG);
text_slider = new Paint();
text_slider.setColor(Color.GREEN);
text_slider.setTextSize(40);
text_slider.setFlags(Paint.ANTI_ALIAS_FLAG);
absoluteMinValue = minValue;
absoluteMaxValue = maxValue;
leftThumbColor = leftThumbColorNormal;
leftThumb = getBitmap(leftDrawable);
leftThumbPressed = getBitmap(leftDrawablePressed);
leftThumbPressed = (leftThumbPressed == null) ? leftThumb : leftThumbPressed;
thumbWidth = getThumbWidth();
thumbHeight = getThumbHeight();
barHeight = getBarHeight();
barPadding = getBarPadding();
_paint = new Paint(Paint.ANTI_ALIAS_FLAG);
_rect = new RectF();
rectLeftThumb = new RectF();
pressedThumb = null;
setMinStartValue();
setWillNotDraw(false);
}
//////////////////////////////////////////
// PUBLIC METHODS
//////////////////////////////////////////
public CrystalSeekbar setCornerRadius(float cornerRadius) {
this.cornerRadius = cornerRadius;
return this;
}
public CrystalSeekbar setMinValue(float minValue) {
this.minValue = minValue;
this.absoluteMinValue = minValue;
return this;
}
public CrystalSeekbar setMaxValue(float maxValue) {
this.maxValue = maxValue;
this.absoluteMaxValue = maxValue;
return this;
}
public CrystalSeekbar setMinStartValue(float minStartValue) {
this.minStartValue = minStartValue;
return this;
}
public CrystalSeekbar setSteps(float steps) {
this.steps = steps;
return this;
}
public CrystalSeekbar setBarColor(int barColor) {
this.barColor = barColor;
return this;
}
public CrystalSeekbar setBarHighlightColor(int barHighlightColor) {
this.barHighlightColor = barHighlightColor;
return this;
}
public CrystalSeekbar setLeftThumbColor(int leftThumbColorNormal) {
this.leftThumbColorNormal = leftThumbColorNormal;
return this;
}
public CrystalSeekbar setLeftThumbHighlightColor(int leftThumbColorPressed) {
this.leftThumbColorPressed = leftThumbColorPressed;
return this;
}
public CrystalSeekbar setLeftThumbDrawable(int resId) {
setLeftThumbDrawable(ContextCompat.getDrawable(getContext(), resId));
return this;
}
public CrystalSeekbar setLeftThumbDrawable(Drawable drawable) {
setLeftThumbBitmap(getBitmap(drawable));
return this;
}
public CrystalSeekbar setLeftThumbBitmap(Bitmap bitmap) {
leftThumb = bitmap;
return this;
}
public CrystalSeekbar setLeftThumbHighlightDrawable(int resId) {
setLeftThumbHighlightDrawable(ContextCompat.getDrawable(getContext(), resId));
return this;
}
public CrystalSeekbar setLeftThumbHighlightDrawable(Drawable drawable) {
setLeftThumbHighlightBitmap(getBitmap(drawable));
return this;
}
public CrystalSeekbar setLeftThumbHighlightBitmap(Bitmap bitmap) {
leftThumbPressed = bitmap;
return this;
}
public CrystalSeekbar setDataType(int dataType) {
this.dataType = dataType;
return this;
}
public CrystalSeekbar setPosition(int pos) {
this.nextPosition = pos;
return this;
}
public void setOnSeekbarChangeListener(OnSeekbarChangeListener onSeekbarChangeListener) {
this.onSeekbarChangeListener = onSeekbarChangeListener;
if (this.onSeekbarChangeListener != null) {
this.onSeekbarChangeListener.valueChanged(getSelectedMinValue());
}
}
public void setOnSeekbarFinalValueListener(OnSeekbarFinalValueListener onSeekbarFinalValueListener) {
this.onSeekbarFinalValueListener = onSeekbarFinalValueListener;
}
public Thumb getPressedThumb() {
return pressedThumb;
}
public RectF getLeftThumbRect() {
return rectLeftThumb;
}
public float getCornerRadius() {
return cornerRadius;
}
public float getMinValue() {
return minValue;
}
public float getMaxValue() {
return maxValue;
}
public float getMinStartValue() {
return minStartValue;
}
public float getSteps() {
return steps;
}
public int getBarColor() {
return barColor;
}
public int getBarHighlightColor() {
return barHighlightColor;
}
public int getLeftThumbColor() {
return leftThumbColor;
}
public int getLeftThumbColorPressed() {
return leftThumbColorPressed;
}
public Drawable getLeftDrawable() {
return leftDrawable;
}
public Drawable getLeftDrawablePressed() {
return leftDrawablePressed;
}
public int getDataType() {
return dataType;
}
public int getPosition() {
return this.position;
}
public float getThumbWidth() {
return (leftThumb != null) ? leftThumb.getWidth() : getThumbDiameter();
}
public float getThumbHeight() {
return (leftThumb != null) ? leftThumb.getHeight() : getThumbDiameter();
}
protected float getThumbDiameter() {
return (thumbDiameter > 0) ? thumbDiameter : 60;
}
public float getBarHeight() {
return (thumbHeight * 0.5f) * 0.3f;
}
public float getDiameter(final TypedArray typedArray) {
return typedArray.getDimensionPixelSize(R.styleable.CrystalRangeSeekbar_thumb_diameter, getResources().getDimensionPixelSize(R.dimen.thumb_height));
}
public float getBarPadding() {
return thumbWidth * 0.5f;
}
public Number getSelectedMinValue() {
double nv = normalizedMinValue;
if (steps > 0 && steps <= ((absoluteMaxValue) / 2)) {
float stp = steps / (absoluteMaxValue - absoluteMinValue) * 100;
double half_step = stp / 2;
double mod = nv % stp;
if (mod > half_step) {
nv = nv - mod;
nv = nv + stp;
} else {
nv = nv - mod;
}
} else {
if (steps != NO_STEP)
throw new IllegalStateException("steps out of range " + steps);
}
nv = (position == Position.LEFT) ? nv : Math.abs(nv - maxValue);
return formatValue(normalizedToValue(nv));
}
public Number getSelectedMaxValue() {
double nv = normalizedMaxValue;
if (steps > 0 && steps <= (absoluteMaxValue / 2)) {
float stp = steps / (absoluteMaxValue - absoluteMinValue) * 100;
double half_step = stp / 2;
double mod = nv % stp;
if (mod > half_step) {
nv = nv - mod;
nv = nv + stp;
} else {
nv = nv - mod;
}
} else {
if (steps != NO_STEP)
throw new IllegalStateException("steps out of range " + steps);
}
return formatValue(normalizedToValue(nv));
}
public void apply() {
// reset normalize min and max value
//normalizedMinValue = 0d;
//normalizedMaxValue = 100d;
thumbWidth = (leftThumb != null) ? leftThumb.getWidth() : getResources().getDimension(R.dimen.thumb_width);
thumbHeight = (leftThumb != null) ? leftThumb.getHeight() : getResources().getDimension(R.dimen.thumb_height);
barHeight = (thumbHeight * 0.5f) * 0.3f;
barPadding = thumbWidth * 0.5f;
// set min start value
if (minStartValue < minValue) {
minStartValue = 0;
setNormalizedMinValue(minStartValue);
} else if (minStartValue > maxValue) {
minStartValue = maxValue;
setNormalizedMinValue(minStartValue);
} else {
//minStartValue = (long)getSelectedMinValue();
if (nextPosition != position) {
minStartValue = (float) Math.abs(normalizedMaxValue - normalizedMinValue);
}
if (minStartValue > minValue) {
minStartValue = Math.min(minStartValue, absoluteMaxValue);
minStartValue -= absoluteMinValue;
minStartValue = minStartValue / (absoluteMaxValue - absoluteMinValue) * 100;
}
setNormalizedMinValue(minStartValue);
position = nextPosition;
}
invalidate();
if (onSeekbarChangeListener != null) {
onSeekbarChangeListener.valueChanged(getSelectedMinValue());
}
}
//////////////////////////////////////////
// PROTECTED METHODS
//////////////////////////////////////////
protected int getTextToDrawColor(final TypedArray typedArray) {
return typedArray.getColor(R.styleable.CrystalRangeSeekbar_text_draw_color, Color.BLACK);
}
protected Bitmap getBitmap(Drawable drawable) {
return (drawable != null) ? ((BitmapDrawable) drawable).getBitmap() : null;
}
protected float getCornerRadius(final TypedArray typedArray) {
return typedArray.getFloat(R.styleable.CrystalRangeSeekbar_corner_radius, 0f);
}
protected float getMinValue(final TypedArray typedArray) {
return typedArray.getFloat(R.styleable.CrystalRangeSeekbar_min_value, 0f);
}
protected float getMaxValue(final TypedArray typedArray) {
return typedArray.getFloat(R.styleable.CrystalRangeSeekbar_max_value, 100f);
}
protected float getMinStartValue(final TypedArray typedArray) {
return typedArray.getFloat(R.styleable.CrystalRangeSeekbar_min_start_value, minValue);
}
protected float getSteps(final TypedArray typedArray) {
return typedArray.getFloat(R.styleable.CrystalRangeSeekbar_steps, NO_STEP);
}
protected int getBarColor(final TypedArray typedArray) {
return typedArray.getColor(R.styleable.CrystalRangeSeekbar_bar_color, Color.GRAY);
}
protected int getBarHighlightColor(final TypedArray typedArray) {
return typedArray.getColor(R.styleable.CrystalRangeSeekbar_bar_highlight_color, Color.BLACK);
}
protected int getLeftThumbColor(final TypedArray typedArray) {
return typedArray.getColor(R.styleable.CrystalRangeSeekbar_left_thumb_color, Color.BLACK);
}
protected int getLeftThumbColorPressed(final TypedArray typedArray) {
return typedArray.getColor(R.styleable.CrystalRangeSeekbar_left_thumb_color_pressed, Color.DKGRAY);
}
protected Drawable getLeftDrawable(final TypedArray typedArray) {
return typedArray.getDrawable(R.styleable.CrystalRangeSeekbar_left_thumb_image);
}
protected Drawable getLeftDrawablePressed(final TypedArray typedArray) {
return typedArray.getDrawable(R.styleable.CrystalRangeSeekbar_left_thumb_image_pressed);
}
protected int getDataType(final TypedArray typedArray) {
return typedArray.getInt(R.styleable.CrystalRangeSeekbar_data_type, DataType.INTEGER);
}
protected final int getPosition(final TypedArray typedArray) {
final int pos = typedArray.getInt(R.styleable.CrystalRangeSeekbar_position, Position.LEFT);
normalizedMinValue = (pos == Position.LEFT) ? normalizedMinValue : normalizedMaxValue;
return pos;
}
protected void setupBar(final Canvas canvas, final Paint paint, final RectF rect) {
rect.left = barPadding;
rect.top = 0.5f * (getHeight() - barHeight);
rect.right = getWidth() - barPadding;
rect.bottom = 0.5f * (getHeight() + barHeight);
paint.setStyle(Paint.Style.FILL);
paint.setColor(barColor);
paint.setAntiAlias(true);
drawBar(canvas, paint, rect);
}
protected void drawBar(final Canvas canvas, final Paint paint, final RectF rect) {
int partsStart = (int) rect.left + (int) (barHeight / 2);
int spacing = (int) (rect.right - rect.left) / (numberOfCircle-1);
for (int i = 0; i < numberOfCircle; i++) {
textBounds = new Rect();
text_paint.getTextBounds(text_draw[i], 0, text_draw[i].length(), textBounds);
int mTextWidth = Math.round(text_paint.measureText(text_draw[i].toString())); // Use measureText to calculate width
int mTextHeight = textBounds.height();
int padding=0;
if (i == 5) {
padding = 10;
}
canvas.drawText(text_draw[i], partsStart - ((mTextWidth / 2f))-padding , rect.bottom + 100, text_paint);
canvas.drawCircle(partsStart, getHeight() / 2, 20, paint);
mCircle_Points_x.add(partsStart);
partsStart = partsStart + spacing;
}
canvas.drawRoundRect(rect, cornerRadius, cornerRadius, paint);
}
protected void setupHighlightBar(final Canvas canvas, final Paint paint, final RectF rect) {
if (position == Position.RIGHT) {
rect.left = normalizedToScreen(normalizedMinValue) + (getThumbWidth() / 2);
rect.right = getWidth() - (getThumbWidth() / 2);
} else {
rect.left = getThumbWidth() / 2;
rect.right = normalizedToScreen(normalizedMinValue) + (getThumbWidth() / 2);
}
paint.setColor(barHighlightColor);
drawHighlightBar(canvas, paint, rect);
}
protected void drawHighlightBar(final Canvas canvas, final Paint paint, final RectF rect) {
canvas.drawRoundRect(rect, cornerRadius, cornerRadius, paint);
paint.setColor(barHighlightColor);
paint.setStyle(Paint.Style.FILL);
for (int i = 0; i < numberOfCircle; i++) {
if (mCircle_Points_x.get(i) <= currentSlidingX) {
canvas.drawCircle(mCircle_Points_x.get(i), getHeight() / 2, 20, paint);
}
}
}
protected void setupLeftThumb(final Canvas canvas, final Paint paint, final RectF rect) {
leftThumbColor = (Thumb.MIN.equals(pressedThumb)) ? leftThumbColorPressed : leftThumbColorNormal;
paint.setColor(leftThumbColor);
rectLeftThumb.left = normalizedToScreen(normalizedMinValue)+getLeft();
rectLeftThumb.right = Math.min(rectLeftThumb.left + (getThumbWidth() / 2) + barPadding, getWidth());
rectLeftThumb.top = 100; // 100 is neccessary to make it a circle
rectLeftThumb.bottom = getHeight() / 2 - 40; // bottom y
circle_center_x = (normalizedToScreen(normalizedMinValue))+(getThumbWidth()/2);
circle_center_y = getHeight() / 2-80;
canvas.drawCircle( (normalizedToScreen(normalizedMinValue))+(getThumbWidth()/2),getHeight() / 2-80, radius_circle, paint);
//drawLeftThumbWithColor(canvas, paint, rectLeftThumb);
textBounds = new Rect();
text_slider.getTextBounds(String.valueOf(getSelectedMinValue()), 0, String.valueOf(getSelectedMinValue()).length(), textBounds);
int mTextWidth = Math.round(text_slider.measureText(String.valueOf(getSelectedMinValue()))); // Use measureText to calculate width
int mTextHeight = textBounds.height();
canvas.drawText(String.valueOf(getSelectedMinValue()),(normalizedToScreen(normalizedMinValue))+(getThumbWidth()/2)-(mTextWidth/2),(getHeight() / 2-80)-((text_slider.descent() + text_slider.ascent()) / 2),text_slider);
}
protected void drawLeftThumbWithColor(final Canvas canvas, final Paint paint, final RectF rect) {
canvas.drawOval(rect, paint);
}
protected void drawLeftThumbWithImage(final Canvas canvas, final Paint paint, final RectF rect, final Bitmap image) {
canvas.drawBitmap(image, rect.left, rect.top, paint);
}
protected void trackTouchEvent(MotionEvent event) {
final int pointerIndex = event.findPointerIndex(mActivePointerId);
try {
final float x = event.getX(pointerIndex);
currentSlidingX = x;
if (Thumb.MIN.equals(pressedThumb)) {
setNormalizedMinValue(screenToNormalized(x));
}
} catch (Exception ignored) {
}
}
protected void touchDown(final float x, final float y) {
}
protected void touchMove(final float x, final float y) {
}
protected void touchUp(final float x, final float y) {
}
protected int getMeasureSpecWith(int widthMeasureSpec) {
int width = 200;
if (MeasureSpec.UNSPECIFIED != MeasureSpec.getMode(widthMeasureSpec)) {
width = MeasureSpec.getSize(widthMeasureSpec);
}
return width;
}
protected int getMeasureSpecHeight(int heightMeasureSpec) {
int height = Math.round(thumbHeight + 400);
if (MeasureSpec.UNSPECIFIED != MeasureSpec.getMode(heightMeasureSpec)) {
height = Math.min(height, MeasureSpec.getSize(heightMeasureSpec));
}
return height;
}
protected final void log(Object object) {
Log.d("CRS=>", String.valueOf(object));
}
//////////////////////////////////////////
// PRIVATE METHODS
//////////////////////////////////////////
private void setMinStartValue() {
if (minStartValue > minValue && minStartValue < maxValue) {
minStartValue = Math.min(minStartValue, absoluteMaxValue);
minStartValue -= absoluteMinValue;
minStartValue = minStartValue / (absoluteMaxValue - absoluteMinValue) * 100;
setNormalizedMinValue(minStartValue);
}
}
private Thumb evalPressedThumb(float touchX) {
Thumb result = null;
boolean minThumbPressed = isInThumbRange(touchX, normalizedMinValue);
if (minThumbPressed) {
// if both thumbs are pressed (they lie on top of each other), choose the one with more room to drag. this avoids "stalling" the thumbs in a corner, not being able to drag them apart anymore.
result = Thumb.MIN;
}
return result;
}
private boolean isInThumbRange(float touchX, double normalizedThumbValue) {
float thumbPos = normalizedToScreen(normalizedThumbValue);
float left = thumbPos - (getThumbWidth() / 2);
float right = thumbPos + (getThumbWidth() / 2);
float x = touchX - (getThumbWidth() / 2);
if (thumbPos > (getWidth() - thumbWidth))
x = touchX;
return (x >= left && x <= right);
}
private void onStartTrackingTouch() {
mIsDragging = true;
}
private void onStopTrackingTouch() {
mIsDragging = false;
}
private float normalizedToScreen(double normalizedCoord) {
float width = getWidth() - (barPadding * 2);
return (float) normalizedCoord / 100f * width;
}
private double screenToNormalized(float screenCoord) {
double width = getWidth();
if (width <= 2 * barPadding) {
// prevent division by zero, simply return 0.
return 0d;
} else {
width = width - (barPadding * 2);
double result = screenCoord / width * 100d;
result = result - (barPadding / width * 100d);
result = Math.min(100d, Math.max(0d, result));
return result;
}
}
private void setNormalizedMinValue(double value) {
normalizedMinValue = Math.max(0d, Math.min(100d, Math.min(value, normalizedMaxValue)));
invalidate();
}
private void setNormalizedMaxValue(double value) {
normalizedMaxValue = Math.max(0d, Math.min(100d, Math.max(value, normalizedMinValue)));
invalidate();
}
private double normalizedToValue(double normalized) {
double val = normalized / 100 * (maxValue - minValue);
val = (position == Position.LEFT) ? val + minValue : val;
return val;
}
private void attemptClaimDrag() {
if (getParent() != null) {
getParent().requestDisallowInterceptTouchEvent(true);
}
}
private <T extends Number> Number formatValue(T value) throws IllegalArgumentException {
final Double v = (Double) value;
if (dataType == DataType.LONG) {
return v.longValue();
}
if (dataType == DataType.DOUBLE) {
return v;
}
if (dataType == DataType.INTEGER) {
return Math.round(v);
}
if (dataType == DataType.FLOAT) {
int hours = (int) v.floatValue();
int minutes = (int) (v.floatValue() * 60) % 60;
int seconds = (int) (v.floatValue() * (60*60)) % 60;
return Math.round(v.floatValue()*100.0)/100.0;
//return v.floatValue();
}
if (dataType == DataType.SHORT) {
return v.shortValue();
}
if (dataType == DataType.BYTE) {
return v.byteValue();
}
throw new IllegalArgumentException("Number class '" + value.getClass().getName() + "' is not supported");
}
//////////////////////////////////////////
// OVERRIDE METHODS
//////////////////////////////////////////
@Override
protected synchronized void onDraw(Canvas canvas) {
super.onDraw(canvas);
// prevent render is in edit mode
if (isInEditMode()) return;
// setup bar
setupBar(canvas, _paint, _rect);
// setup seek bar active range line
setupHighlightBar(canvas, _paint, _rect);
// draw left thumb
setupLeftThumb(canvas, _paint, _rect);
}
@Override
protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(getMeasureSpecWith(widthMeasureSpec), getMeasureSpecHeight(heightMeasureSpec));
}
/**
* Handles thumb selection and movement. Notifies listener callback on certain events.
*/
@Override
public synchronized boolean onTouchEvent(MotionEvent event) {
if (!isEnabled())
return false;
final int action = event.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
setPressed(true);
invalidate();
mIsDragging = touchinCircle(event.getX(), event.getY(), circle_center_x, circle_center_y, radius_circle) ;
break;
case MotionEvent.ACTION_MOVE:
if (mIsDragging) {
currentSlidingX = event.getX();
setNormalizedMinValue(screenToNormalized(event.getX()));
}
if (onSeekbarChangeListener != null) {
onSeekbarChangeListener.valueChanged(getSelectedMinValue());
}
break;
case MotionEvent.ACTION_UP:
Log.i("ACTION_UP","Yes");
if (mIsDragging) {
touchinCircle(event.getX(), event.getY(), circle_center_x, circle_center_y, radius_circle) ;
mIsDragging =false;
setPressed(false);
if (onSeekbarFinalValueListener != null) {
onSeekbarFinalValueListener.finalValue(getSelectedMinValue());
}
} else {
// Touch up when we never crossed the touch slop threshold
// should be interpreted as a tap-seek to that location.
mIsDragging = true;
touchinCircle(event.getX(), event.getY(), circle_center_x, circle_center_y, radius_circle) ;
mIsDragging = false;
}
// pressedThumb = null;
invalidate();
if (onSeekbarChangeListener != null) {
onSeekbarChangeListener.valueChanged(getSelectedMinValue());
}
break;
case MotionEvent.ACTION_POINTER_DOWN: {
break;
}
case MotionEvent.ACTION_POINTER_UP:
invalidate();
break;
case MotionEvent.ACTION_CANCEL:
if(mIsDragging)
{
mIsDragging =false;
setPressed(false);
}
invalidate(); // see above explanation
break;
}
return true;
}
private boolean touchinCircle(float x, float y, float circleCenterX, float circleCenterY, float circleRadius) {
double dx = Math.pow(x - circleCenterX, 2);
double dy = Math.pow(y - circleCenterY, 2);
if ((dx + dy) < Math.pow(circleRadius, 2)) {
currentSlidingX = x;
setNormalizedMinValue(screenToNormalized(x));
return true;
} else {
return false;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment