在 ImageView 中设置 scaleType="centerCrop" 动画

animate scaleType="centerCrop" in ImageView

有没有办法让 scaleType="centerCrop" 动起来?我需要将图像缩放到 certerCrop,以便图像可以覆盖 imageView 的整个区域。但是我需要在图像缩放之前对其进行动画处理以向用户展示图像的实际外观我打算这样做

imageView.animate().scaleX(2.0f).setDuration(2000)

但问题是我将在幻灯片放映的多张图片上执行此操作,因此每张图片都会有不同的大小和方向。

我也找到了这个库 https://github.com/flavioarfaria/KenBurnsView 但在使用时仍然遇到问题。

非常感谢任何帮助。

已编辑

开始处理 KenBurnsView 仍然无法将图像平移到中心。

我写了一个自定义ImageView来支持ScaleTypes之间的动画,希望对你有帮助。请原谅我糟糕的英语,这不是我的母语。

用法:

AnimatedImageView animatedImageView = new AnimatedImageView(context) or findViewById(R.id.animated_image_view);
animatedImageView.setAnimatedScaleType(ImageView.ScaleType.CENTER_CROP);
animatedImageView.setAnimDuration(1000); // default is 500
animatedImageView.setStartDelay(500);
animatedImageView.startAnimation;

A​​nimatedImageView

/**
 * Custom ImageView that can animate ScaleType
 * Originally created by Wflei on 16/5/31.
 * Updated by Mike Miller (https://mikemiller.design) on 6/15/2017.
 * Original Whosebug Post - 
 */
public class AnimatedImageView extends android.support.v7.widget.AppCompatImageView {

    // Listener values;
    private ScaleType mFromScaleType, mToScaleType;
    private ValueAnimator mValueAnimator;
    private int mStartDelay = 0;
    private boolean isViewLayedOut = false;

    // Constructors
    public AnimatedImageView(Context context) {
        this(context, null);
    }

    public AnimatedImageView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public AnimatedImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        // Set default original scale type
        mFromScaleType = getScaleType();

        // Set default scale type for animation
        mToScaleType = getScaleType();

        // Init value animator
        mValueAnimator = ValueAnimator.ofFloat(0f, 1f);

        // Set resource
        updateScaleType(mFromScaleType, false);
    }

    /**
     * Sets the scale type we want to animate to
     *
     * @param toScaleType
     */
    public void setAnimatedScaleType(ScaleType toScaleType) {
        mToScaleType = toScaleType;
    }

    /**
     * Duration of the animation
     *
     * @param animationDuration
     */
    public void setAnimDuration(int animationDuration) {
        mValueAnimator.setDuration(animationDuration);
    }

    /**
     * Set the time delayed for the animation
     *
     * @param startDelay The delay (in milliseconds) before the animation
     */
    public void setStartDelay(Integer startDelay) {
        mStartDelay = startDelay == null ? 0 : startDelay;
    }

    @Override
    public void setScaleType(ScaleType scaleType) {
        super.setScaleType(scaleType);
        mFromScaleType = scaleType;
    }

    @Override
    public void setImageDrawable(Drawable drawable) {
        super.setImageDrawable(drawable);
        updateScaleType(mFromScaleType, false);
    }

    @Override
    public void setImageBitmap(Bitmap bm) {
        super.setImageBitmap(bm);
        updateScaleType(mFromScaleType, false);
    }

    @Override
    public void setImageResource(int resId) {
        super.setImageResource(resId);
        updateScaleType(mFromScaleType, false);
    }

    @Override
    public void setImageURI(Uri uri) {
        super.setImageURI(uri);
        updateScaleType(mFromScaleType, false);
    }

    /**
     * Animates the current view
     * and updates it's current asset
     */
    public void startAnimation() {

        // This will run the animation with a delay (delay is defaulted at 0)
        postDelayed(startDelay, mStartDelay);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);

        // View has been laid out
        isViewLayedOut = true;

        // Animate change when bounds are official
        if (changed) {
            updateScaleType(mToScaleType, false);
        }
    }

    /**
     * animate to scaleType
     *
     * @param toScaleType
     */
    private void updateScaleType(final ScaleType toScaleType, boolean animated) {

        // Check if view is laid out
        if (!isViewLayedOut) {
            return;
        }

        // Cancel value animator if its running
        if (mValueAnimator != null && mValueAnimator.isRunning()) {
            mValueAnimator.cancel();
            mValueAnimator.removeAllUpdateListeners();
        }

        // Set the  scale type
        super.setScaleType(mFromScaleType);

        // Get values for the current image matrix
        setFrame(getLeft(), getTop(), getRight(), getBottom());
        Matrix srcMatrix = getImageMatrix();
        final float[] srcValues = new float[9], destValues = new float[9];
        srcMatrix.getValues(srcValues);

        // Set the scale type to the new type
        super.setScaleType(toScaleType);
        setFrame(getLeft(), getTop(), getRight(), getBottom());
        Matrix destMatrix = getImageMatrix();
        if (toScaleType == ScaleType.FIT_XY) {
            float sX = ((float) getWidth()) / getDrawable().getIntrinsicWidth();
            float sY = ((float) getHeight()) / getDrawable().getIntrinsicHeight();
            destMatrix.postScale(sX, sY);
        }
        destMatrix.getValues(destValues);

        // Get translation values
        final float transX = destValues[2] - srcValues[2];
        final float transY = destValues[5] - srcValues[5];
        final float scaleX = destValues[0] - srcValues[0];
        final float scaleY = destValues[4] - srcValues[4];

        // Set the scale type to a matrix
        super.setScaleType(ScaleType.MATRIX);

        // Listen to value animator changes
        mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = animation.getAnimatedFraction();
                float[] currValues = Arrays.copyOf(srcValues, srcValues.length);
                currValues[2] = srcValues[2] + transX * value;
                currValues[5] = srcValues[5] + transY * value;
                currValues[0] = srcValues[0] + scaleX * value;
                currValues[4] = srcValues[4] + scaleY * value;
                Matrix matrix = new Matrix();
                matrix.setValues(currValues);
                setImageMatrix(matrix);
            }
        });

        // Save the newly set scale type after animation completes
        mValueAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);

                // Set the from scale type to the newly used scale type
                mFromScaleType = toScaleType;
            }
        });

        // Start the animation
        if (animated) {
            mValueAnimator.start();
        } 
    }
}