Android:ImageView旋转动画-保持比例类型适合中心 [英] Android: ImageView rotation animation - keep scale type fit center

查看:150
本文介绍了Android:ImageView旋转动画-保持比例类型适合中心的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ImageView,其中有 android:scaleType = fitCenter

I have an ImageView that has android:scaleType="fitCenter"

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="at.lukle.picturerotation.MainActivity">

    <ImageView
        android:id="@+id/iv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="fitCenter"
        android:src="@drawable/android"/>

    <Button
        android:id="@+id/btn_rotate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:text="rotate"/>

</RelativeLayout>

它看起来像这样:

< a href = https://i.stack.imgur.com/5FzuZ.png rel = nofollow noreferrer>

单击按钮时,我会应用旋转动画:

When the Button gets clicked, I apply a rotation animation:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button btnRotate = (Button) findViewById(R.id.btn_rotate);
        final ImageView iv = (ImageView) findViewById(R.id.iv);

        btnRotate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                iv.animate().rotationBy(90f).start();
            }
        });
    }
}

现在看起来像这样:

图像在侧面被切割。我希望scaleType也适用于旋转的图像,以便ImageView不仅可以旋转,而且可以缩放以适合宽度。我想我也需要缩放动画,但是我不知道该怎么做。

The image gets cut on the side. I want that the scaleType is also applied on the rotated image, so that the ImageView not just gets rotated, but also scaled to fit the width. I guess I need a scaling animation too, but I have no idea how to do that.

我也尝试只使用 iv.setRotation( 90),但我在这里也遇到同样的问题...

I also tried to just use iv.setRotation(90), but I have the same problem here...

推荐答案

为此,请按照以下步骤操作步骤:

To do this follow these steps:


  1. scaleType 设置为矩阵:

  1. set scaleType to matrix:




 <ImageView ...
    android:scaleType="matrix"/>





  1. 在onCreate,将图像加载到imageview并设置onClick侦听器的旋转按钮:




imageView.post(new Runnable() {
            @Override
            public void run() {
                Bitmap bitmap= BitmapFactory.decodeResource(getResources(),R.drawable.dummy);


           imageView.setImageBitmap(bitmap);

            if (bitmap.getWidth() > 0) {

                float scale = ((float)imageView.getMeasuredWidth())/((float)imageView.getDrawable().getIntrinsicWidth());

                imageView.getLayoutParams().height = (int)(scale * imageView.getDrawable().getIntrinsicHeight());
                imageView.setImageMatrix(scaleMatrix(scale, scale));
            }
        }
    });


btnRotate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
              animateImageHeight(imageView,btnRotate);
            }
        });




  1. 在活动中添加animateImageHeight方法:

void animateImageHeight(最终ImageView imageView,最终按钮btnRotate){

void animateImageHeight(final ImageView imageView, final Button btnRotate){

    final float drawableWidth = imageView.getDrawable().getIntrinsicWidth();
    final float drawableHeight = imageView.getDrawable().getIntrinsicHeight();
    float viewWidth = imageView.getMeasuredWidth();
    final float viewHeight = imageView.getMeasuredHeight();
    final int rotation = imageRotation % 360;
    final int newRotation = (rotation + 90);

    final int newViewHeight;
    final float imageScale;
    final float newImageScale;

    if (rotation==0 || rotation==180)
    {
        imageScale = viewWidth / drawableWidth;
        newImageScale = viewWidth / drawableHeight;
        newViewHeight = (int)(drawableWidth * newImageScale);
    }
    else if (rotation==90 || rotation==270){
        imageScale = viewWidth / drawableHeight;
        newImageScale = viewWidth / drawableWidth;
        newViewHeight = (int)(drawableHeight * newImageScale);
    }
    else{
        throw new UnsupportedOperationException("rotation can 0, 90, 180 or 270. ${rotation} is unsupported");
    }


    ValueAnimator animator= ValueAnimator.ofFloat(0f,1f) .setDuration(1000L);



    animator.setInterpolator(new AccelerateDecelerateInterpolator());

    animator.addListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animator) {
            btnRotate.setEnabled(false);
        }

        @Override
        public void onAnimationEnd(Animator animator) {
            imageRotation = newRotation % 360;
            btnRotate.setEnabled(true);
        }

        @Override
        public void onAnimationCancel(Animator animator) {

        }

        @Override
        public void onAnimationRepeat(Animator animator) {

        }
    });

    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            float animVal = (float)animation.getAnimatedValue();
            float complementaryAnimVal = 1 - animVal;

            int animatedHeight =
                    (int)(complementaryAnimVal * viewHeight + animVal * newViewHeight);
            float animatedScale =
                    (complementaryAnimVal * imageScale + animVal * newImageScale);
            float animatedRotation =
                    (complementaryAnimVal * rotation + animVal * newRotation);


            imageView.getLayoutParams().height=animatedHeight;

            Matrix matrix=
                    rotationMatrix(
                    animatedRotation,
                    drawableWidth / 2,
                    drawableHeight / 2
            );

            matrix.postScale(
                    animatedScale,
                    animatedScale,
                    drawableWidth / 2,
                    drawableHeight / 2);
            matrix.postTranslate(-(drawableWidth - imageView.getMeasuredWidth())/2, -(drawableHeight - imageView.getMeasuredHeight())/2);

            imageView.setImageMatrix(matrix);

            imageView.requestLayout();
        }
    });

    animator.start();
}

您可以找到kotlin版本和完整的演示此处

You can find the kotlin version and the complete demonstration here.

这篇关于Android:ImageView旋转动画-保持比例类型适合中心的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆