Cześć,
znalazłem trochę czasu aby zająć się pickerem, jednak mam pewien problem.
Gdy zmienia się ćwiartka okręgu zmieniają się wartości i nie wiem jak narysować od początku do kliknięcia łuk...
Oto kod:
public class Arc extends View {
private static final String TAG = Arc.class.getSimpleName();
private float mThickness = 50f; // grubość linii
private int mRotate = 0; // przesunięcie okręgu w stopniach
private Paint mCircleBgPaint; // rysowanie ścieżki (tła okręgu)
private int mCircleEndAngle = 270; // koniec łuku
private int mCircleStartAngle = 0; // początek łuku
private int mCircleSweepAngle = 0; // aktualny kąt
private RectF mCircleOuterBounds;
private int mCircleBgColor = Color.RED; // kolor okręgu
private Paint mCirclePaint; // progressbar
private int mCircleColor = Color.BLUE; // kolor progressbar
private Paint mEraserPaint;
private RectF mCircleInnerBounds;
private int mEraserColor = Color.YELLOW; // kolor wypełnienia okręgu
private boolean mEraserInnerBackground = true; // czy czyścić wypełnienie
private Bitmap mBitmap;
private Canvas mCanvas;
private float mMinValue = 0; // minimalna wartość
private float mMaxValue = 100; // maksymalna wartość
private boolean mEnabled; // rysować kropkę
private float mDotSize; // wielkość kropki
private Paint mCircleThumbPaint;
private float mTranslateX; // środek okręgu (oś X)
private float mTranslateY; // środek okręgu (oś Y)
private boolean mTouchInside; // czy dotyk w środku zmienia położenie punktu
private int mArcRadius; // długość promienia
private int mThumbXPos; // środek kropki (oś X)
private int mThumbYPos; // środek kropki (oś Y)
public Arc(Context context) {
super(context);
initDefaultValue(context, 0, null);
}
public Arc(Context context, AttributeSet attrs) {
super(context, attrs);
initDefaultValue(context, 0, attrs);
}
public Arc(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initDefaultValue(context, defStyleAttr, attrs);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public Arc(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
initDefaultValue(context, defStyleAttr, attrs);
}
private void initDefaultValue(Context context, int defStyleAttr, AttributeSet attrs) {
mCircleBgPaint = new Paint();
mCircleBgPaint.setAntiAlias(true);
mCircleBgPaint.setColor(mCircleBgColor);
mCirclePaint = new Paint();
mCirclePaint.setAntiAlias(true);
mCirclePaint.setColor(mCircleColor);
mEraserPaint = new Paint();
mEraserPaint.setAntiAlias(true);
mEraserPaint.setColor(mEraserColor);
if (mEraserInnerBackground) {
mEraserPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
}
mCircleThumbPaint = new Paint();
mCircleThumbPaint.setAntiAlias(true);
mCircleThumbPaint.setColor(Color.CYAN);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
if (w != oldw || h != oldh) {
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mBitmap.eraseColor(Color.TRANSPARENT);
mCanvas = new Canvas(mBitmap);
}
super.onSizeChanged(w, h, oldw, oldh);
updateBounds();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
int min = Math.min(widthMeasureSpec, heightMeasureSpec);
this.setMeasuredDimension(parentWidth, parentHeight);
this.setTouchInSide(this.mTouchInside);
super.onMeasure(min, min);
}
@Override
protected void onDraw(Canvas canvas) {
mCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
mCanvas.drawArc(mCircleOuterBounds, (mCircleStartAngle + mRotate), (mCircleEndAngle - mCircleStartAngle), true, mCircleBgPaint);
if (mCircleSweepAngle - mRotate > 0f) {
mCanvas.drawArc(mCircleOuterBounds, (mCircleStartAngle + mRotate), (mCircleSweepAngle - mRotate), true, mCirclePaint);
}
mCanvas.drawOval(mCircleInnerBounds, mEraserPaint);
if (mEnabled) {
// x = cx + r * cos(a)
mThumbXPos = (int) (mTranslateX + (mArcRadius * Math.cos(Math.toRadians(this.mCircleSweepAngle))));
// y = cy + r * sin(a)
mThumbYPos = (int) (mTranslateY + (mArcRadius * Math.sin(Math.toRadians(this.mCircleSweepAngle))));
mCanvas.drawCircle(mThumbXPos, mThumbYPos, mThickness, mCircleThumbPaint);
}
canvas.drawBitmap(mBitmap, 0, 0, null);
}
private void updateBounds() {
if (this.getPaddingLeft() < (mThickness / 2)) {
this.setPadding((int) (mThickness / 2), this.getPaddingTop(), this.getPaddingRight(), this.getPaddingBottom());
}
mCircleOuterBounds = new RectF(0 + this.getPaddingLeft(), 0 + this.getPaddingLeft(), getWidth() - this.getPaddingLeft(), getHeight() - this.getPaddingLeft());
mCircleInnerBounds = new RectF(
mCircleOuterBounds.left + mThickness,
mCircleOuterBounds.top + mThickness,
mCircleOuterBounds.right - mThickness,
mCircleOuterBounds.bottom - mThickness);
this.mTranslateX = mCircleOuterBounds.centerX();
this.mTranslateY = mCircleOuterBounds.centerY();
this.mArcRadius = (int) (mTranslateX - this.getPaddingLeft() - (mThickness / 2));
invalidate();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
//return super.onTouchEvent(event);
if (this.mEnabled) {
this.getParent().requestDisallowInterceptTouchEvent(true);
switch (event.getAction()) {
case 0:
this.updateOnTouch(event);
break;
case 1:
this.setPressed(false);
this.getParent().requestDisallowInterceptTouchEvent(false);
break;
case 2:
this.updateOnTouch(event);
break;
case 3:
this.setPressed(false);
this.getParent().requestDisallowInterceptTouchEvent(false);
}
return true;
} else {
return false;
}
}
public void setTouchInSide(boolean isEnabled) {
this.mTouchInside = isEnabled;
}
private void updateOnTouch(MotionEvent event) {
boolean ignoreTouch = this.ignoreTouch(event.getX(), event.getY());
if (!ignoreTouch) {
this.setPressed(true);
this.mCircleSweepAngle = (int) this.getTouchDegrees(event.getX(), event.getY());
this.invalidate();
}
}
private double getTouchDegrees(float xPos, float yPos) {
double angle = (int) (Math.atan2(yPos - mTranslateY, xPos - mTranslateX) * 180 / Math.PI);
Log.d(TAG, "R=" + mArcRadius);
Log.d(TAG, "śrX=" + mTranslateX);
Log.d(TAG, "śrY=" + mTranslateY);
Log.d(TAG, "x=" + xPos);
Log.d(TAG, "y=" + yPos);
Log.d(TAG, "kat=" + angle);
if (angle < 0) {
angle += 360;
}
return angle;
}
private boolean ignoreTouch(float xPos, float yPos) {
boolean ignore = false;
double touchRadius = Math.sqrt(Math.pow(xPos - this.mTranslateX, 2) + Math.pow(yPos - this.mTranslateY, 2));
if (this.mTouchInside && touchRadius > this.mArcRadius) {
ignore = true;
} else {
if ((touchRadius > (this.mArcRadius + (this.mThickness / 2))) ||
(touchRadius < (this.mArcRadius - (this.mThickness / 2)))) {
ignore = true;
}
}
return ignore;
}
}
byłbym wdzięczny za pomoc