Android – Drawable: Understanding canvas width and height

androidandroid-drawabledrawable

I try to implement my own drawable that will corss fade from a simple colored rectangle (that should have the same size as the ImageView where the drawable is in) to a loaded bitmap (over http).

So what I do is override the draw() method of my Drawable:

public void draw(Canvas canvas) {
        boolean done = true;

        Log.d("Test",
                "canvas w: " + canvas.getWidth() + " " + canvas.getHeight());


        final int alpha = mAlpha;
        final boolean crossFade = mCrossFade;

        Paint paint = mStartPaint;
        paint.setColor(blueColor);

        if (!crossFade || 255 - alpha > 0) {
            if (crossFade) {
                paint.setAlpha(255 - alpha);
            }

            // Draw the rect with the color
            canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), paint);

            if (crossFade) {
                paint.setAlpha(0xFF);
            }

        }

        if (alpha > 0) {
            Bitmap bitmap = mEnd;
            paint = mEndPaint;
            paint.setAlpha(alpha);
            if (mBitmapScalingType == null)
                canvas.drawBitmap(bitmap, mEndX, mEndY, paint);
            else
                mBitmapScalingType.draw(bitmap, canvas.getWidth(),
                        canvas.getHeight(), canvas, paint);

            paint.setAlpha(0xFF);
        }

        if (!done) {
            mHandler.post(mInvalidater);
        }
    }

So the canvas.getWidth() and canvas.getHeight() returns 128 (width) and 150 (height) which is the same as the ImageView has. But the result is:

enter image description here

The blue rectangle has not been painted over the complete canvas and I can't get figure out why.

The ImageView that displays my fadeable drawable has no specific scaletype set.

Any ideas what could be wrong?

I have also noticed that the width and height calculated from setBounds() is 180 x 212 px

@Override
public void setBounds(int left, int top, int right, int bottom) {
    super.setBounds(left, top, right, bottom);

    final int width = right - left;
    final int height = bottom - top;
            Log.d("Test", "width: "+width+" height: "+height);
     } 

and if I draw the color with 180 x 212 px

canvas.drawRect(0, 0, 180, 212, paint);

the rectangular is now drawn to fill the canvas completely.

Any idea what could be wrong?

Btw. The ImageView is defined like that:

<ImageView android:id="@+id/playerPic"
           android:layout_width="64dp"
           android:layout_height="75dp"           
           android:layout_marginRight="10dp"
           />

in xhdpi 64dp = 128px and 75dp = 150 px

Best Answer

This answer doesn't explain the difference in dimensions, but sometimes it's easier to just do things a different way.

If you just want to fill the canvas with a color, you don't need to use drawRect(), just use drawColor(). There's the simple version that just takes a Color, and one that lets you specify a porter-duff mode. This way you don't need dimensions at all, and you can avoid the whole thing.