Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-cloud-platform/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何使用使用使用矩阵缩放的ImageView设置缩小动画_Android - Fatal编程技术网

Android 如何使用使用使用矩阵缩放的ImageView设置缩小动画

Android 如何使用使用使用矩阵缩放的ImageView设置缩小动画,android,Android,所以我有一个ImageView,它使用一个矩阵来缩放我正在显示的位图。我可以双击放大到全尺寸,我的缩放动画处理放大的动画,一切正常 现在我想再次双击以缩小,但当我使用ScaleAnimation设置动画时,ImageView不会在当前视口收缩时绘制图像的新曝光区域,而是会看到可见图像的部分在缩小。我尝试过使用ViewGroup.setClipChildrenfalse,但这只会留下上一帧中最后绘制的瑕疵-导致三倍伸缩效果,但不完全是我想要的效果 我知道有许多与缩放相关的问题,但没有一个涉及到我的

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

现在我想再次双击以缩小,但当我使用ScaleAnimation设置动画时,ImageView不会在当前视口收缩时绘制图像的新曝光区域,而是会看到可见图像的部分在缩小。我尝试过使用ViewGroup.setClipChildrenfalse,但这只会留下上一帧中最后绘制的瑕疵-导致三倍伸缩效果,但不完全是我想要的效果

我知道有许多与缩放相关的问题,但没有一个涉及到我的情况——特别是设置缩小操作的动画。我有机械工作-即除了缩小动画,双击放大和缩小工程罚款


有什么建议吗?

最后,我决定停止使用Android提供的动画类,因为ScaleAnimation将一个比例应用于ImageView作为一个整体,然后与ImageView的图像矩阵的比例相结合,这使得我的工作变得复杂,除了剪辑问题。 因为我真正需要的是动画化对ImageView的矩阵所做的更改,所以我在本文末尾实现了OnDoubleTapListener——我把它作为一个练习留给读者添加缺少的字段和方法——我使用一些PointF和矩阵字段来避免过多的垃圾创建。基本上,动画本身是通过使用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提供的动画类,因为ScaleAnimation将一个比例应用于ImageView作为一个整体,然后与ImageView的图像矩阵的比例相结合,这使得工作变得复杂,除了剪辑问题之外。 因为我真正需要的是动画化对ImageView的矩阵所做的更改,所以我在本文末尾实现了OnDoubleTapListener——我把它作为一个练习留给读者添加缺少的字段和方法——我使用一些PointF和矩阵字段来避免过多的垃圾创建。基本上,动画本身是通过使用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;
    }

您好……我喜欢您的代码,但……您没有提供calculateFitToScreenScale方法代码……您能为我提供吗……?您好……我喜欢您的代码,但……您没有提供calculateFitToScreenScale方法代码……您能为我提供吗。。。。。?