gpt4 book ai didi

android - 如何使用使用矩阵缩放的 ImageView 动画缩小

转载 作者:行者123 更新时间:2023-11-29 15:30:24 26 4
gpt4 key购买 nike

所以我有一个 ImageView 使用 Matrix 来缩放我正在显示的位图。我可以双击放大到全尺寸,我的 ScaleAnimation 处理放大动画,一切正常。

现在我想再次双击以缩小,但是当我使用 ScaleAnimation 对此进行动画处理时,ImageView 不会绘制图像的新曝光区域(因为当前视口(viewport)缩小),而是您看到可见部分图像缩小。我试过使用 ViewGroup.setClipChildren(false),但这只会留下前一帧的最后绘制的伪影 - 导致幻觉伸缩效果,但不是我想要的。

我知道有很多与缩放相关的问题,但没有一个能涵盖我的情况 - 特别是动画缩小操作。我确实有机制在工作——即除了缩小动画之外,双击放大和缩小效果很好。

有什么建议吗?

最佳答案

最后我决定停止使用 Android 提供的 Animation 类,因为 ScaleAnimation 将比例应用于 ImageView 作为一个整体,然后与 ImageView 的图像矩阵的比例相结合,使得使用起来很复杂(除了从我遇到的剪裁问题)。因为我真正需要的是对 ImageView 的矩阵所做的更改进行动画处理,所以我实现了 OnDoubleTapListener(在这篇文章的结尾——我把它作为“给读者的练习”来添加缺失的字段和方法——我使用很少有 PointF 和 Matrix 字段,以避免产生过多的垃圾)。基本上,动画本身是通过使用 View.post 不断发布一个 Runnable 来实现的,该 Runnable 会逐渐更改 ImageView 的图像矩阵:

public boolean onDoubleTap(MotionEvent e) {
final float x = e.getX();
final float y = e.getY();
matrix.reset();
matrix.set(imageView.getImageMatrix());
matrix.getValues(matrixValues);
matrix.invert(inverseMatrix);
doubleTapImagePoint[0] = x;
doubleTapImagePoint[1] = y;
inverseMatrix.mapPoints(doubleTapImagePoint);
final float scale = matrixValues[Matrix.MSCALE_X];
final float targetScale = scale < 1.0f ? 1.0f : calculateFitToScreenScale();
final float finalX;
final float finalY;
// assumption: if targetScale is less than 1, we're zooming out to fit the screen
if (targetScale < 1.0f) {
// scaling the image to fit the screen, we want the resulting image to be centred. We need to take
// into account the shift that is applied to zoom on the tapped point, easiest way is to reuse
// the transformation matrix.
RectF imageBounds = new RectF(imageView.getDrawable().getBounds());
// set up matrix for target
matrix.reset();
matrix.postTranslate(-doubleTapImagePoint[0], -doubleTapImagePoint[1]);
matrix.postScale(targetScale, targetScale);
matrix.mapRect(imageBounds);

finalX = ((imageView.getWidth() - imageBounds.width()) / 2.0f) - imageBounds.left;
finalY = ((imageView.getHeight() - imageBounds.height()) / 2.0f) - imageBounds.top;
}
// else zoom around the double-tap point
else {
finalX = x;
finalY = y;
}

final Interpolator interpolator = new AccelerateDecelerateInterpolator();
final long startTime = System.currentTimeMillis();
final long duration = 800;
imageView.post(new Runnable() {
@Override
public void run() {
float t = (float) (System.currentTimeMillis() - startTime) / duration;
t = t > 1.0f ? 1.0f : t;
float interpolatedRatio = interpolator.getInterpolation(t);
float tempScale = scale + interpolatedRatio * (targetScale - scale);
float tempX = x + interpolatedRatio * (finalX - x);
float tempY = y + interpolatedRatio * (finalY - y);
matrix.reset();
// translate initialPoint to 0,0 before applying zoom
matrix.postTranslate(-doubleTapImagePoint[0], -doubleTapImagePoint[1]);
// zoom
matrix.postScale(tempScale, tempScale);
// translate back to equivalent point
matrix.postTranslate(tempX, tempY);
imageView.setImageMatrix(matrix);
if (t < 1f) {
imageView.post(this);
}
}
});

return false;
}

关于android - 如何使用使用矩阵缩放的 ImageView 动画缩小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7418955/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com