I am trying to develop a custom component i.e. arc slider, I am done with the arc and the thumb but not able to figure out how can I draw the rounded edge arc and also the embossed effect in it. at the moment the slider looks something like this
the code for drawing the arc is
private void drawSlider(Canvas canvas) {
float sweepDegrees = (value * arcWidthInAngle)
/ (maximumValue - minimumValue);
// the grey empty part of the circle
drawArc(canvas, startAngle, arcWidthInAngle, mTrackColor);
// the colored "filled" part of the circle
drawArc(canvas, startAngle, sweepDegrees, mFillColor);
// the thumb to drag.
int radius = ((diameter/2) - (mArcThickness/2));
Point thumbPoint = calculatePointOnArc(centerX, centerY, radius, startAngle + sweepDegrees);
thumbPoint.x = thumbPoint.x - (mThumbDiameter/2);
thumbPoint.y = thumbPoint.y - (mThumbDiameter/2);
Bitmap thumbBitmap = BitmapFactory.decodeResource(
mContext.getResources(), R.drawable.circle25);
thumbBitmap = getResizedBitmap(thumbBitmap, mThumbDiameter, mThumbDiameter);
canvas.drawBitmap(thumbBitmap, thumbPoint.x, thumbPoint.y,
null);
}
private void drawArc(Canvas canvas, float startAngle, float sweepDegrees,
Paint paint) {
if (sweepDegrees <= 0 || sweepDegrees > arcWidthInAngle) {
return;
}
path.reset();
path.arcTo(outerCircle, startAngle, sweepDegrees);
path.arcTo(innerCircle, startAngle + sweepDegrees, -sweepDegrees);
// innerCircle.
path.close();
canvas.drawPath(path, paint);
}
I am aiming for the arc something like this
For the rounded edges, you can use the Paint.setStrokeCap() method. Also, the default paint cap is BUTT. You should use the Paint.Cap.ROUND cap instead.
For example:
Paint mFillColor = new Paint();
mFillColor.setStrokeCap(Paint.Cap.ROUND)
I managed to build the arc some what like below
What I did is I calculated the arc starting and ending point and there I draw the circle with diameter equal to arc thickness.
The code for this is
private void drawSlider(Canvas canvas) {
float sweepDegrees = (value * arcWidthInAngle)
/ (maximumValue - minimumValue);
// the grey empty part of the arc
drawArc(canvas, startAngle, arcWidthInAngle, mTrackColor);
// the colored "filled" part of the arc
drawArc(canvas, startAngle, sweepDegrees, mFillColor);
// the thumb to drag.
int radius = ((diameter/2) - (mArcThickness/2));
Point thumbPoint = calculatePointOnArc(centerX, centerY, radius, startAngle + sweepDegrees);
thumbPoint.x = thumbPoint.x - (mThumbDiameter/2);
thumbPoint.y = thumbPoint.y - (mThumbDiameter/2);
Bitmap thumbBitmap = BitmapFactory.decodeResource(
mContext.getResources(), R.drawable.circle25);
thumbBitmap = getResizedBitmap(thumbBitmap, mThumbDiameter, mThumbDiameter);
canvas.drawBitmap(thumbBitmap, thumbPoint.x, thumbPoint.y,
null);
//drawArc(canvas, startAngle, startAngle + sweepDegrees, white);
}
private void drawArc(Canvas canvas, float startAngle, float sweepDegrees,
Paint paint) {
if (sweepDegrees <= 0 || sweepDegrees > arcWidthInAngle) {
return;
}
path.reset();
int radius = ((diameter/2) - (mArcThickness/2));
Point startPoint = calculatePointOnArc(centerX, centerY, radius, startAngle);
Point endPoint = calculatePointOnArc(centerX, centerY, radius, startAngle + sweepDegrees);
path.arcTo(outerCircle, startAngle, sweepDegrees);
path.arcTo(innerCircle, startAngle + sweepDegrees, -sweepDegrees);
// drawing the circle at both the end point of the arc to git it rounded look.
path.addCircle(startPoint.x, startPoint.y, mArcThickness/2, Path.Direction.CW);
path.addCircle(endPoint.x, endPoint.y, mArcThickness/2, Path.Direction.CW);
path.close();
canvas.drawPath(path, paint);
}
// this is to calculate the end points of the arc
private Point calculatePointOnArc(int circleCeX, int circleCeY, int circleRadius, float endAngle)
{
Point point = new Point();
double endAngleRadian = endAngle * (Math.PI / 180);
int pointX = (int) Math.round((circleCeX + circleRadius * Math.cos(endAngleRadian)));
int pointY = (int) Math.round((circleCeY + circleRadius * Math.sin(endAngleRadian)));
point.x = pointX;
point.y = pointY;
return point;
}
// for the emboss effect set maskfilter of the paint to EmbossMaskFilter
private Paint mTrackColor = new Paint();
MaskFilter mEmboss = new EmbossMaskFilter(new float[] { 0.0f, -1.0f, 0.5f},
0.8f, 15, 1.0f);
mTrackColor.setMaskFilter(mEmboss);
Use the Paint.setStrokeCap() method. You need Paint.Cap.ROUND. The default one is Paint.Cap.BUTT. There is a similar Path property that is called path join. It determines how to draw the parts of the path where it's constituent segments join. To set it use Path.setPathJoin(). You might need it in the future. Good luck.
You are using path to draw the arc. Use CornerPathEffect
to round the corners. Example here CornerPathEffect example
.
And here is the example for embossed effect. I'm not sure if it is what you want.
Embossed effect example
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With