1

I recently updated my Android app (see source on Github) to use Android Studio 0.6.0, which required bumping the build-tools to v19.1.0 (from v19.0.1), the Android Gradle plugin to v0.11 (from 0.9), and the Gradle wrapper to 1.12 (from 1.11).

Before the above changes (at this commit), the app was successfully drawing squares on a canvas to show signal strength of GLONASS satellites (see IDs 87 and 88):

enter image description here

After updating my Android tools and launching via Android Studio or gradlew installDebug, the squares suddenly disappeared (see IDs 77, 87, 88):

enter image description here

The code that draws the square, with a center of (x,y), is:

canvas.drawRect(x - SAT_OFFSET, y + SAT_OFFSET, x + SAT_OFFSET, y - SAT_OFFSET, mSatelliteStrokePaint);

(see Github for full class)

The commit with all changes to update to Android Studio 0.6.0 can be seen here.

Why did canvas.drawRect() suddenly stop working after updating the Android tools?

Sean Barbeau
  • 11,496
  • 8
  • 58
  • 111

2 Answers2

4

Apparently this has something to do with Android handling invalid input values for drawRect(), triggered by Android Gradle Plugin 0.11 enabling the new manifest merging tool by default.

If I add useOldManifestMerger true to my build.gradle, then the squares return:

android {
    compileSdkVersion 19
    buildToolsVersion "19.1.0"
    useOldManifestMerger true
    ...
}

The underlying problem was that Canvas.drawRect() takes in the parameters (float left, float top, float right, float bottom, Paint paint)

I had the top and bottom coordinates of the rectangle reversed, so the top value (which should have been the smallest y value) was the larger y value, and the bottom value (which should have been the largest y value) was the smallest y value (the origin (0,0) is in the upper left corner).

Before Android Studio 0.6.0 tool updates, Android was correcting invalid input and still drawing the square. After Android Studio 0.6.0 tool update started using the new manifest merging tool, Android is no longer correcting invalid input and instead it doesn't draw anything.

After changing my code to reverse the top/bottom y values of the square:

c.drawRect(x - SAT_OFFSET, y - SAT_OFFSET, x + SAT_OFFSET, y + SAT_OFFSET, mSatelliteStrokePaint);

...the squares reappeared (even when using the new manifest merger - i.e., without adding useOldManifestMerger true to build.gradle).

So, the correct way to fix this issue is to reverse the top/bottom coordinates of the square to be valid input, and still use the new manifest merger.

Sean Barbeau
  • 11,496
  • 8
  • 58
  • 111
0

This is ridiculous - we have been 'drawing rectangles backwards' for over 30 years. There are valid programmatic reasons to draw backwards sometimes.

Use the following if you need this functionality.

public static void drawRectOriented(Canvas g, float x1,float y1,float x2,float y2,Paint p) {
    if (x1 > x2) {
        float t = x2;
        x2 = x1;
        x1 = t;
    }
    if (y1 > y2) {
        float t = y2;
        y2 = y1;
        y1 = t;
    }
    g.drawRect(x1,y1,x2,y2, p);
}
Lorne K
  • 109
  • 7