2

The code:

int width = canvas.getWidth();
int height = canvas.getHeight();

int shift = 0;
RectF rect = new RectF(0 + shift, 0 + shift, width - 1 - shift, height - 1 - shift);

Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(30);
paint.setColor(0xff009900);

float angle_step = 180 / 5;

for (int i=0; i<5; i++) {
  canvas.drawArc(rect, 180 + angle_step * i, angle_step, true, paint);
}

The result:

The question: How to make inner stroke instead of outer?

Thanks

MobileX
  • 409
  • 4
  • 13
  • 3
    It's getting cut off on the edges because you're not accounting for the stroke width. You need to inset your `rect` by at least half the `Paint`'s stroke width on each edge. Then setting the `Paint`'s stroke join to `Paint.Join.ROUND` would probably take care of the "spikes" on the bottom. – Mike M. Feb 23 '17 at 20:37
  • "Paint.Join.ROUND" - it gives rounded corners on the left and on the right. "you're not accounting for the stroke width" - I don't like the idea to calculate something here. It's obvious that inner stroke solves the issue. Doesn't Android support that? – MobileX Feb 23 '17 at 21:51
  • Answer is no - android doen't support that. http://stackoverflow.com/questions/15309029/android-paint-stroke-width-positioning – j2ko Feb 23 '17 at 21:56
  • That's not good. Shame on them. – MobileX Feb 23 '17 at 22:09
  • 1
    Yeah, @j2ko is right about the stroke centering, unless it's changed in a recent version, but you'd still have to account for older versions. As far as the rounded corners, whether you round, bevel, whatever, you'll probably just have to change the stroke join type for the first and last segments, or do miter for everything, and adjust that with `setStrokeMiter()`. Or you could draw something afterward to "erase" those spikes, but that seems a little superfluous. – Mike M. Feb 23 '17 at 22:10
  • 1
    @ Mike M, thanks. I'd like to accept your answer. But I can't as you've written that as a comment. Upvoted. – MobileX Feb 23 '17 at 22:23
  • @MikeM. just thought about the stroke miter, prepare the example and you get the answer first again). Now it's looks like I'm just following your comments :) Sorry for that. – j2ko Feb 23 '17 at 22:32
  • Nah, it's cool. @j2ko took the time to write a proper answer (and gave credit!). It's all theirs. Thanks, though. Glad we could help. Cheers! – Mike M. Feb 23 '17 at 22:37

1 Answers1

4

As @Mike M (all credits goes to him) mentioned the solution would be as following:

UPDATE: instead of using Paint.Joint.Round you could use mitter limit as following:

    int width = canvas.getWidth();
    int height = canvas.getHeight();

    int shift = 0;
    RectF rect = new RectF(0 + shift, 0 + shift, width - 1 - shift, height - 1 - shift);

    Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    paint.setStyle(Paint.Style.STROKE);

    //Make stroke mitter to affect only very sharp angles
    paint.setStrokeMiter(1.8f);

    int strokeWidth = 30;
    paint.setStrokeWidth(strokeWidth);
    paint.setColor(0xff009900);

    //inset drawing rect by the half of stroke width
    rect.inset(strokeWidth/2,strokeWidth/2);

    float angle_step = 180 / 5;

    for (int i=0; i<5; i++) {
        canvas.drawArc(rect, 180 + angle_step * i, angle_step, true, paint);
    }

This will give you sharp adges on left and right.

The result:

enter image description here

j2ko
  • 2,479
  • 1
  • 16
  • 29