Bryan Herbst
Bryan Herbst

Reputation: 67259

Only the first of three custom views draws properly

I have a custom ScoreView that consists of two lines of text (a name and a score). Behind that text, I am drawing a bar representing the score.

I have a fragment that contains three such ScoreViews. When I update the ScoreViews with a new name or score, everything works fine. However, if I update the rectangle behind them, only the first rectangle is redrawn.

The end result is something like this:

All three ScoreViews should have a gray bar behind the text.

To prevent the possibility of my fill color attribute causing this, I am statically setting the bar's color in the ScoreView.

ScoreView snippet:

public class ScoreView extends View {

    public void setFillPercent(float percent) {
        mFillPercent = percent;
        mFillRect = new Rect(getLeft(), getTop(), getLeft() + Math.round(mFillPercent*getWidth()), getBottom());
        invalidate();
        requestLayout();
    }

    @Override
    protected void onSizeChanged (int w, int h, int oldw, int oldh) {
        mFillRect = new Rect(getLeft(), getTop(), getLeft() + Math.round(mFillPercent*w), getBottom());
        mTextXPos = getLeft() + 20; // TODO dp?
        mNameTextYPos = h/2 - (int)mNameTextSize;
        mScoreTextYPos = h/2 + (int)mScoreTextSize;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawRect(mFillRect, mFillPaint);
        canvas.drawText(mName, mTextXPos, mNameTextYPos, mNameTextPaint);
        canvas.drawText(String.valueOf(mScore), mTextXPos, mScoreTextYPos, mScoreTextPaint);
    }
}

In my fragment, I call:

oneScoreView.setFillPercent(.5f);
twoScoreView.setFillPercent(.5f);
threeScoreView.setFillPercent(.5f);

I set a breakpoint in onDraw() and I can see that it is being called, and that mFillRect has the correct size and position. It simply doesn't get displayed.

I also discovered that if I rearrange the three ScoreViews, it is always the first ScoreView that updates properly.

Upvotes: 0

Views: 68

Answers (1)

Volodymyr Lykhonis
Volodymyr Lykhonis

Reputation: 2976

I am not sure, but mFillRect = new Rect(getLeft(), getTop(), getLeft() it means you set offset left and top of the view, but then you use this rectangle to draw inside the same view. I think it's just out of view's canvas area, that's why you cannot see it. I might be wrong though.

Upvotes: 1

Related Questions