draw rounded edge arc in android with embossed effect

左心房为你撑大大i 提交于 2019-12-03 02:46:29

问题


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


回答1:


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)



回答2:


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



回答3:


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




回答4:


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.



来源:https://stackoverflow.com/questions/10784208/draw-rounded-edge-arc-in-android-with-embossed-effect

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!