1

I created this drawing using the canvas but after doing so, for some reason I annoyingly get a black line appearing in-between the leftmost red rectangle & the grey rectangle containing the number 1. What can be done to get rid of that line?

enter image description here

public class RectangleTextView extends View {
    private final Paint mBackPaint = new Paint();
    private final Paint mRedPaint = new Paint();

    private TextPaint mTextPaint;

    public RectangleTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        int valueInPx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics());
        int valueInSp = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20, getResources().getDisplayMetrics());

        mRedPaint.setColor(Color.RED);

        mBackPaint.setAntiAlias(false);
        mBackPaint.setColor(Color.BLACK);
        mBackPaint.setStrokeWidth(valueInPx);
        mBackPaint.setStyle(Paint.Style.STROKE);

        mTextPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
        mTextPaint.setColor(Color.BLACK);
        mTextPaint.setTextAlign(Paint.Align.CENTER);
        mTextPaint.setTextSize(valueInSp);

        String pageTitle = getResources().getString(R.string.app_name);
    }

    @Override protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (getWidth() == 0)
            return;

        //draw end rectangles
        int mSideRectWidth = 10;
        canvas.drawRect(0, 0, mSideRectWidth, getHeight(), mRedPaint); //draw left end rectangle
        canvas.drawRect(getWidth() - mSideRectWidth, 0, getWidth(), getHeight(), mRedPaint); //draw right end rectangle

        //draw grey boxes
        setBackgroundColor(Color.parseColor("#808080"));
        int boxWidth = (getWidth() - mSideRectWidth) / 7;


        for (int i = 0; i < 7; i++) {
            //draw black lines
            canvas.drawLine(mSideRectWidth + boxWidth * i, 0, mSideRectWidth + boxWidth * i, getHeight(), mBackPaint);

            //draw text views
            canvas.drawText(Integer.toString(i + 1), (i * boxWidth) + (boxWidth / 2), ((canvas.getHeight() / 2) - ((mTextPaint.descent() + mTextPaint.ascent()) / 2)), mTextPaint);
        }
    }
}
wbk727
  • 8,017
  • 12
  • 61
  • 125
  • Your "7" rectangle is also narrower than the others - looks like a bug in the code you used to create the image. Post the code, that will help. – Jim Aug 15 '15 at 23:12
  • 1
    And your battery is low :) – Jim Aug 15 '15 at 23:12
  • Is this unexpected line drawn by you? It's hard to tell, but it looks like it's part of the background, in which case there's some empty space between the red rectangle and first gray one. – Karakuri Aug 15 '15 at 23:12
  • You are drawing 7 lines, so that is to be expected? You should either guard against drawing the first line, or add a line after the for loop. If wanted I can clarify in an answer. – Emz Aug 15 '15 at 23:23
  • @Emz Please clarify that. I don't want that line there at all – wbk727 Aug 15 '15 at 23:25
  • Also please accept the answer that you went with. I see too many questions with answers that aren't accepted. – Emz Aug 15 '15 at 23:33

3 Answers3

1

You don't want the "1st" black line, so skip the "0" index.. like so:

    for (int i = 1; i < 7; i++) {
        //draw black lines
        canvas.drawLine(mSideRectWidth + boxWidth * i, 0, (mSideRectWidth/2) + boxWidth * i, getHeight(), mBackPaint);
    }

    for (int i = 0; i < 7; i++) {
        //draw text views
        canvas.drawText(Integer.toString(i + 1), (i * boxWidth) + (boxWidth / 2), ((canvas.getHeight() / 2) - ((mTextPaint.descent() + mTextPaint.ascent()) / 2)), mTextPaint);
    }

That should help.

EDIT: Also, you did not account for the red line on the left, so you will not be "centered" (since there is a line on each side, you need to only reduce it by 1/2):

    for (int i = 1; i < 7; i++) {
        //draw black lines
        canvas.drawLine((mSideRectWidth/2) + boxWidth * i, 0, mSideRectWidth + boxWidth * i, getHeight(), mBackPaint);
    }

    for (int i = 0; i < 7; i++) {
        //draw text views
        canvas.drawText(Integer.toString(i + 1), (mSideRectWidth / 2) + (i * boxWidth) + (boxWidth / 2), ((canvas.getHeight() / 2) - ((mTextPaint.descent() + mTextPaint.ascent()) / 2)), mTextPaint);
    }
Jim
  • 10,172
  • 1
  • 27
  • 36
  • That will also remove the first number. An `if` is needed. Or some more elegant solution. See my answer for details. – Emz Aug 15 '15 at 23:27
  • @Jim Brilliant. Just realised that before you posted it lol. Also do you why the heck the text view numbers aren't exactly center aligned horizontally yet it is vertically? I know that `(i * boxWidth) + (boxWidth / 2)` has got something to do with it but I don't know what. – wbk727 Aug 15 '15 at 23:33
  • I cannot check your math on `boxWidth` - you may have to reduce it as well (based on the look of things, you need to subtract the width of 1 red line from that calculation) – Jim Aug 15 '15 at 23:45
  • @Jim Do you know what's I'm doing wrong in this [question?](http://stackoverflow.com/questions/32037260/how-to-add-rectangles-on-top-of-existing-rectangle-in-canvas) I've added necessary code to my class file but the red rectangles are still not being drawn. I believe some code (possibly another loop) to resolve this is missing but I don't know what to add. – wbk727 Aug 17 '15 at 17:04
1
for (int i = 0; i < 7; i++) {
    //draw black lines
    canvas.drawLine(mSideRectWidth + boxWidth * i, 0, mSideRectWidth + boxWidth * i, getHeight(), mBackPaint);
...
}

You call drawLine 7 times, i = 0.1.2..6. Instead do it like this.

for (int i = 0; i < 7; i++) {
    //draw black lines
    if (i != 0) { // guards against the first line from ever being renderd
        canvas.drawLine(mSideRectWidth + boxWidth * i, 0, mSideRectWidth + boxWidth * i, getHeight(), mBackPaint);
    }
...
}

And you will get rid of that line, as you do not want the first line to be drawn, you want it to act as a separator.

There are numerous other options such as making the pairs and linking them. You can guard against the last and draw the line after. This was the most simple solution that sprung to mind.

Emz
  • 1,280
  • 1
  • 14
  • 29
  • Do you know why the heck the text view numbers aren't exactly center aligned horizontally but yet they are vertically? I know that `(i * boxWidth) + (boxWidth / 2)` has got something to do with it but I don't know what. – wbk727 Aug 15 '15 at 23:39
  • 1
    Quick guess: `(i * boxWidth + 1)` as your line is `1px` as well. I am unable to try it however. – Emz Aug 15 '15 at 23:40
1
for (int i = 0; i < 7; i++) {
        //draw black lines
        canvas.drawLine(mSideRectWidth + boxWidth * i, 0, mSideRectWidth + boxWidth * i, getHeight(), mBackPaint);

your loop draws 7 black lines, and I think you only want 6 lines by removing the first one far on the left.

try this:

for (int i = 0; i < 7; i++) {
        //draw black lines
        if(i>0)
        canvas.drawLine(mSideRectWidth + boxWidth * i, 0, mSideRectWidth + boxWidth * i, getHeight(), mBackPaint);

        //draw text views
        canvas.drawText(Integer.toString(i + 1), (i * boxWidth) + (boxWidth / 2), ((canvas.getHeight() / 2) - ((mTextPaint.descent() + mTextPaint.ascent()) / 2)), mTextPaint);
    }
derfect
  • 622
  • 2
  • 6
  • 14
  • Even though it is only one line, I still recommend to use `{}`. More can be read [here](http://stackoverflow.com/questions/8020228/is-it-ok-if-i-omit-curly-braces-in-java) about it. – Emz Aug 15 '15 at 23:30
  • thanks but I personally don't like using them, the less brackets the better :) – derfect Aug 15 '15 at 23:38
  • I recommend having a read over [here](https://blog.codecentric.de/en/2014/02/curly-braces/). – Emz Aug 15 '15 at 23:39
  • thanks Emz, i'm going to stick with this quote from your link "Those braces aren’t at fault. A lazy programmer is." – derfect Aug 15 '15 at 23:42
  • @seah0rse Do you know what's I'm doing wrong in this [question?](http://stackoverflow.com/questions/32037260/how-to-add-rectangles-on-top-of-existing-rectangle-in-canvas) I've added necessary code to my class file but the red rectangles are still not being drawn. I believe some code (possibly another loop) to resolve this is missing but I don't know what to add. – wbk727 Aug 17 '15 at 17:04