Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bug with Android 4.3 ImageView method getImageMatrix()

I recently upgraded to Android 4.4 and someone of the features of my app have surprisingly stopped working.

I have this code for initializing and then drawing my custom view. The basic idea is it adjusts the zoom level so the entire view fits on the screen.

private void initAtZoomLevel(float zoomLevel){
    ....
    Matrix transformMatrix = new Matrix();
    transformMatrix.setScale(initialZoomLevel, initialZoomLevel);
    float yTransCenter = (screenHeight - mapHeight)/2.0f;
    setImageMatrix(transformMatrix);
}

protected void onDraw(Canvas canvas){

    super.onDraw(canvas);
    float[] values = new float[9];
    getImageMatrix().getValues(values);
    scaleFactor = values[0];
    ....
}

THIS WORKS ON ANDROID 4.1.2, and 4.2.2 DEVICES I HAVE

But on Android 4.4/4.3 getImageMatrix().getValues(values) stopped working! It returns an identity matrix instead of the transform matrix I expect on app start up!

DEBUG PRINT-OUT:

4.1.2: @setImageMatrix(transformMatrix): transformMatrix = Matrix{[0.025122833, 0.0, 0.0][0.0, 0.025122833, 566.5][0.0, 0.0, 1.0]}

@getImageMatrix().getValues(values): transformMatrix = Matrix{[0.025122833, 0.0, 0.0][0.0, 0.025122833, 566.5][0.0, 0.0, 1.0]}

4.4: @setImageMatrix(transformMatrix): transformMatrix = Matrix{[0.025122833, 0.0, 0.0][0.0, 0.025122833, 553.0][0.0, 0.0, 1.0]}

@getImageMatrix().getValues(values): transformMatrix = Matrix{[1.0, 0.0, 0.0][0.0, 1.0, 0.0][0.0, 0.0, 1.0]}

I've looked around and I can't seem to find any documentation on this. Somehow the image matrix for my view is being reset; has Android 4.4 changed the way we are supposed to do this? Has anyone else run in to this problem?

note: the problem appears to have originated on Android 4.3 - the same problem occurs running on an emulator

UPDATE: I have checked the change log from 4.2 to 4.3, but there is nothing on there I can see above the Matrix Class, or anything relevant to the View class.

UPDATE 2: My pinch-to-zoom is also not working, which uses the same setImageMatrix() method - and it's clearly not sticking because nothing happens in getImageMatrix().getValues()

like image 321
kburbach Avatar asked Dec 06 '13 18:12

kburbach


1 Answers

I have found what I believe to be the problem. I took a look at the source code for ImageView and discovered the setImageMatrix(Matrix matrix) is saving the matrix in a different field than getImageMatrix() is returning...

Android 4.4 ImageView

public void setImageMatrix(Matrix matrix) {
    // collaps null and identity to just null
    if (matrix != null && matrix.isIdentity()) {
        matrix = null;
    }

    // don't invalidate unless we're actually changing our matrix
    if (matrix == null && !mMatrix.isIdentity() ||
            matrix != null && !mMatrix.equals(matrix)) {
        mMatrix.set(matrix);
        configureBounds();
        invalidate();
    }
}

Here the matrix is being stored in the field mMatrix

public Matrix getImageMatrix() {
    if (mDrawMatrix == null) { //<-- should be mMatrix == null
        return new Matrix(Matrix.IDENTITY_MATRIX);
    }
    return mDrawMatrix; //<-- NOT THE RIGHT FIELD TO RETURN
}

While getImageMatrix() returns mDrawMatrix...

Android 4.1.2 ImageView

public Matrix getImageMatrix() {
    return mMatrix;
}

public void setImageMatrix(Matrix matrix) {
    // collaps null and identity to just null
    if (matrix != null && matrix.isIdentity()) {
        matrix = null;
    }

    // don't invalidate unless we're actually changing our matrix
    if (matrix == null && !mMatrix.isIdentity() ||
            matrix != null && !mMatrix.equals(matrix)) {
        mMatrix.set(matrix);
        configureBounds();
        invalidate();
    }
}

both methods use the same field - mMatrix

So there's the problem right there --- all of a sudden getImageMatrix() is returning the wrong field...

like image 113
kburbach Avatar answered Oct 15 '22 06:10

kburbach