旋转带动画的图像

问题描述 投票:21回答:6

是)我有的

我有一个箭头图像(如左图)。当用户点击它时,它应该用动画旋转180度,看起来应该是正确的。

我做了什么

private void rotate(float degree, final int toggleV) {

        final RotateAnimation rotateAnim = new RotateAnimation(0.0f, degree,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f);

        rotateAnim.setDuration(500);
        toggle.startAnimation(rotateAnim);
        rotateAnim.setAnimationListener(new Animation.AnimationListener() {

            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {


                if (toggleV == 1)
                    toggle.setImageResource(R.drawable.toggle_up);
                else
                    toggle.setImageResource(R.drawable.toggle_down);
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
    }

问题

我看到动画工作正常但设置图像时有一点闪烁。可能是因为动画结束和设置图像时的时差。

如何删除此闪烁问题?你有更好的方法吗?

android android-animation android-imageview image-rotation
6个回答
49
投票

首先,您最低SDK要求是什么?如果它至少是Android 3.0,您可以使用更新的动画框架,并使用以下内容为您的Image设置动画:

imageView.animate().rotation(180).start();

关于闪烁:我不会在旋转后重置ImageView的源图像,我只需保留原始图像并确保旋转动画在动画后填充,使图像旋转。闪烁很可能是由于在更改源图像时View的重新布局/重绘造成的。

可能引起进一步的视觉伪像(闪烁?),因为原始旋转的图像和旋转的静态图像可能在几个像素中不同。


4
投票

如果我是你,我会使用ViewPropertyAnimator(可从API 12获得)。它的语法更直接IMO。 用法是:

toggle.animate().rotation(0.5f);

2
投票

为什么不使用RotateAnimation?

在res中创建一个名为anim的文件夹,在res / anim中创建一个名为rotator.xml的文件。

<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="400"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="360"/>

这里一个完整的旋转将在4000毫秒(4秒)内完成。现在添加要旋转到可绘制文件夹中的PNG图像。然后打开res / main.xml,在布局中删除默认的textView后,将ImageView和Button添加到布局中。将ImageView的src属性设置为添加图像的文件名,例如android:src =“@ drawable / myimg”Ok,让我们编辑主类。在按钮的onClick()中,添加运行动画所需的代码。请检查以下代码。

public class AnimationActivity extends Activity {

    public ImageView  myImage ;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        myImage = (ImageView)findViewById(R.id.imageView1);
        final Animation myRotation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.rotator);
        ((Button)findViewById(R.id.button1)).setOnClickListener(new OnClickListener()    {
            @Override
            public void onClick(View arg0) {
                myImage.startAnimation(myRotation);
            }
        });
    }
}

1
投票

如果要保持动画状态,可以使用setFillAfter


1
投票

验证码:(您可以按照我的解决方案)

imageView.setImageResource(R.drawable.ic_arrow_up);

boolean up = true;

if (!up) { 
    up = true; 
    imageView.startAnimation(animate(up)); 
} else { 
    up = false; 
    imageView.startAnimation(animate(up)); 
}

private Animation animate(boolean up) {
    Animation anim = AnimationUtils.loadAnimation(this, up ? R.anim.rotate_up : R.anim.rotate_down);
    anim.setInterpolator(new LinearInterpolator()); // for smooth animation
    return anim;
}

绘制/ ic_arrow_up.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportWidth="24.0"
        android:viewportHeight="24.0">
    <path
        android:fillColor="#3d3d3d"
        android:pathData="M7.41,15.41L12,10.83l4.59,4.58L18,14l-6,-6 -6,6z"/>
</vector>

动画/ rotate_up.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillAfter="true"
    android:fillEnabled="true">
    <rotate
        android:duration="200"
        android:fromDegrees="-180"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toDegrees="0" />
</set>

动画/ rotate_down.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillAfter="true"
    android:fillEnabled="true">
    <rotate
        android:duration="200"
        android:fromDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toDegrees="180" />
</set>

我用过那段代码。因为这会保存动画状态:

android:fillAfter="true"
android:fillEnabled="true"

1
投票

如果要将图像顺时针旋转180度。

private var isExpanded = true

private fun rotateImage(view: View) {
    val startAngle = if (isExpanded) 0f else 180f
    ObjectAnimator.ofFloat(view, View.ROTATION, startAngle, startAngle + 180f).apply {
        duration = 300
        interpolator = LinearInterpolator()
        start()
    }
    isExpanded = !isExpanded
}

或者更简单(如@ Alex.F所写):

view.animate().setDuration(300).rotationBy(180f).start()
© www.soinside.com 2019 - 2024. All rights reserved.