draw rounded edge arc in android with embossed effect

android, android-canvas

Solution

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);

Problem

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

Original source