Android 4.3 ImageView方法的错误getImageMatrix()

时间:2013-12-06 18:48:48

标签: android android-custom-view android-4.4-kitkat android-4.3-jelly-bean

我最近升级到了Android 4.4,并且我应用程序功能的某些人出乎意料地停止了工作。

我有这个代码用于初始化然后绘制我的自定义视图。基本思路是调整缩放级别,使整个视图适合屏幕。

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];
    ....
}

这是关于ANDROID 4.1.2和4.2.2设备的工作

但在Android 4.4 / 4.3 getImageMatrix().getValues(values)停止工作! 它返回一个单位矩阵,而不是我在app启动时期望的变换矩阵!

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]}

我环顾四周,似乎无法找到任何相关文档。不知何故,我的视图的图像矩阵正在重置;安卓4.4改变了我们应该这样做的方式吗?还有其他人遇到过这个问题吗?

注意:问题似乎源自Android 4.3 - 在模拟器上运行同样的问题

更新:我已经检查了change log from 4.2 to 4.3,但我在矩阵类上方或与View类相关的任何内容上都没有任何内容。

更新2 :我的缩放缩放功能也无效,它使用相同的setImageMatrix()方法 - 而且显然没有坚持,因为getImageMatrix().getValues() <没有任何反应/ p>

2 个答案:

答案 0 :(得分:2)

我发现了我认为的问题。我查看了ImageView的源代码,发现setImageMatrix(Matrix matrix)将矩阵保存在与getImageMatrix()返回的字段不同的字段中...

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();
    }
}

此处矩阵存储在 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
}

getImageMatrix()返回 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();
    }
}

两种方法都使用相同的字段 - mMatrix

所以问题就在那里 - 突然getImageMatrix()正在回到错误的领域......

答案 1 :(得分:0)

虽然我之前的回答确实概述了整体问题,但事实上它可能不是一个错误。正如Generic Holiday Name所指出的,mDrawMatrix 应该在mMatrix方法中设置为configureBounds() - 这将消除此问题/错误/无论如何。

HOWEVER ,我必须添加几行代码才能让configureBounds()真正起作用:

private void configureBounds() {
    if (mDrawable == null || !mHaveFrame) {
        return;
    }

    int dwidth = mDrawableWidth;
    int dheight = mDrawableHeight;

    ...

    if (dwidth <= 0 || dheight <= 0 || ScaleType.FIT_XY == mScaleType) {
        /* If the drawable has no intrinsic size, or we're told to
            scaletofit, then we just fill our entire view.
        */
        mDrawable.setBounds(0, 0, vwidth, vheight);
        mDrawMatrix = null;
    } else {
             //here's the where mDrawMatrix == mMatrix IF using scaleType.MATRIX
             ...
    }
}

所以,为了让我的工作方式达到预期的4.2及以下,你需要确保:

  1. mDrawable != null。这不是以前的问题,但对于我的情况,我没有使用drawable,所以一切都失败了(return语句立即被点击)
  2. 'dwidth >0 && dheight >0。如果你有一个真正的绘画,这不是问题,但就像我说的,我没有。
  3. mHaveFrame = true。我不知道这是什么 - 从未使用它。将此设置为true的唯一方法是调用setFrame(int, int, int, int)
  4. 要让我的缩放代码再次运行,我必须添加以下内容:

     //potentially a fix for the "bug" that appears in Android 4.3+
     //mDrawable cannot be null anymore for getImageMatrix to work---stupid
     //therefore the imageview class MUST set a drawable for matrix scaling to work
     //so here I am using a "empty" drawable to get around this
     ShapeDrawable fakeDrawable = new ShapeDrawable(); //so mDrawable != null
     fakeDrawable.setIntrinsicHeight(1); //so dwidth and dheight are > 0
     fakeDrawable.setIntrinsicWidth(1);
    
     setImageDrawable(fakeDrawable);
    
     setFrame(0, 0, viewWidth, viewHeight); //setting a frame so mHaveFrame = true
    

    YIKES