Search code examples
androidcanvasrect

Android canvas draw multiple rectangles of equal distance


I have 4 Strings. I'd like to draw a rectangle around each, and have them be equal distance to each other. I have code that "works" but I need 3 spaces for my last rectangle to make the distance equal, and I don't understand why. I am using an LG G Watch R, in case it is relevant.

private void drawDate(Canvas canvas, float centerX, float centerY)
    {
        float x = centerX + 75f;
        float y = centerY + 50f;
        String dayOfWeek = daysOfWeek[mTime.weekDay] + ",";
        String month = months[mTime.month];
        String monthDay = mTime.monthDay + ",";
        String year = Integer.toString(mTime.year);
        float height = outLinePaint.getTextSize();
        float totalWidth = outLinePaint.measureText(String.format("%s %s %s %s", dayOfWeek, month, monthDay, year));
        final float spaceWidth = outLinePaint.measureText(" ");
        x -= totalWidth/2f;
        outLinePaint.setStyle(Paint.Style.FILL);

        float halfWidth = outLinePaint.measureText(dayOfWeek)/2f;
        canvas.drawRect(x - halfWidth, y - height, x + halfWidth, y + height /2f , whitePaint);
        canvas.drawText(dayOfWeek, x, y, outLinePaint);

        x += (halfWidth*2f)+spaceWidth;
        halfWidth = outLinePaint.measureText(month)/2f;
        canvas.drawRect(x - halfWidth, y - height, x + halfWidth, y + height /2f , whitePaint);
        canvas.drawText(month, x, y, outLinePaint);

        x += (halfWidth*2f)+spaceWidth;
        halfWidth = outLinePaint.measureText(monthDay)/2f;
        canvas.drawRect(x - halfWidth, y - height, x + halfWidth, y + height /2f , whitePaint);
        canvas.drawText(monthDay, x, y, outLinePaint);

        //THIS LINE
        x += (halfWidth*2f)+spaceWidth+spaceWidth+spaceWidth;
        //it looks right on the canvas, but why can I not simply
        //x += (halfWidth*2f)+spaceWidth; like above?
        halfWidth = outLinePaint.measureText(year)/2f;
        canvas.drawRect(x - halfWidth, y - height, x + halfWidth, y + height /2f , whitePaint);
        canvas.drawText(year, x, y, outLinePaint);

        outLinePaint.setStyle(Paint.Style.STROKE);
    }

NOTE: THIS "BUG" ONLY EFFECTS THE LAST STRING

This is what I expect (AND what I get if I use x += (halfWidth*2f)+spaceWidth+spaceWidth+spaceWidth;):

"Correct"

However if I use x += (halfWidth*2f)+spaceWidth; like I do with my other 3, I get:

enter image description here


Solution

  • I have solved it. I could not get @pskink's example to work for the life of me (it didn't draw on my canvas). The problem was my center alignment.

    x was in the middle of my Rect not the left. Whereas I was expecting x to be the leftmost point in my Rect when I added its width to x.

    I have fixed it by setting the text align to left (so that x IS my leftmost point), and changing my drawDate() method to:

    float spaceWidth;
    private void drawDate(float centerX, float centerY)
    {
        float x = centerX + centerX*DATE_AND_COMPASS_X_OFFSET;
        float y = centerY + centerY*DATE_AND_COMPASS_Y_OFFSET;
        String dayOfWeek = daysOfWeek[mTime.weekDay] + ",";
        String month = months[mTime.month];
        String monthDay = mTime.monthDay + ",";
        String year = Integer.toString(mTime.year);
        float height = outLinePaint.getTextSize();
        float totalWidth = outLinePaint.measureText(String.format("%s %s %s %s", dayOfWeek, monthnthDay, year));
        spaceWidth = outLinePaint.measureText(" ");
        outLinePaint.setStyle(Paint.Style.FILL);
        x-=totalWidth/2;
        x+=drawDateInline(dayOfWeek, x, y, height);
        x+=drawDateInline(month, x, y, height);
        x+=drawDateInline(monthDay, x, y, height);
        drawDateInline(year, x, y, height);
        outLinePaint.setStyle(Paint.Style.STROKE);
    }
    
    private float drawDateInline(String word, float x, float y, float height) {
        float width = outLinePaint.measureText(word);
        canvas.drawRect(x, y - height, x + width, y + height /2f, whitePaint);
        canvas.drawText(word, x, y, outLinePaint);
        return width+spaceWidth;
    }
    

    I'm also not sure how this is a "bad approach".