Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.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 使用动画旋转图像_Android_Android Animation_Android Imageview_Image Rotation - Fatal编程技术网

Android 使用动画旋转图像

Android 使用动画旋转图像,android,android-animation,android-imageview,image-rotation,Android,Android Animation,Android Imageview,Image Rotation,我拥有的 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);

我拥有的

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) {

            }
        });
    }
我有一个箭头图像(像左边的那个)。当用户点击它时,它应该随着动画旋转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) {

            }
        });
    }
问题

我看到动画效果很好,但在设置图像时有一点闪烁。可能是因为动画结束和图像设置时存在时间差


如何消除闪烁问题?有更好的方法吗?

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

为什么不使用旋转动画

在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"/>
如果我是你,我会使用(可从API 12获得)。它的语法更直截了当。
用途如下:

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

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

imageView.animate().rotation(180).start();
关于闪烁:我不会在旋转后重置ImageView的源图像,我只会保留原始图像,并确保旋转动画在动画后填充,使图像旋转。闪烁很可能是由更改源图像时视图的重新显示/重画引起的

由于原始旋转图像和旋转静态图像可能在几个像素上存在差异,因此可能会导致进一步的视觉伪影(闪烁?)。

验证代码:(您可以按照我的解决方案进行操作)

可绘制/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>

如果要将图像顺时针旋转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所写):

请注意,如果您过于频繁地旋转图像多次,它不会在0-180-360位置停止。因为如果在上一个动画完成之前启动新动画,它将移动一个角度

因此,一个更好的方法写在公认的答案中。它不依赖于当前动画状态

private var angle = 0f

angle += 180f
view.animate().setDuration(300).rotation(angle).start()

当我按下ImageView时,它只会旋转一次。但在我再次按下它之后,它应该会再次旋转,依此类推。但这并没有发生。有什么想法吗?如果您使用的是我提供的代码示例,那么这段代码特别告诉视图“旋转180度”。因此,如果它已经旋转到180度,那么它将什么也不做。在click listener中,您可以检查视图的当前旋转(.getRotation),如果它不是0,则以类似的方式将其旋转回0。是的,我只是这样做了,它也工作了。现在,有没有一种方法可以在旋转到0时控制动画方向。我的意思是,它在一个特定的方向上旋转,但我想用相反的方式。我想你应该继续在同一个方向上旋转视图,而不是顺时针旋转到180,逆时针旋转回到0。例如,您可以根据用户交互时视图的旋转角度(可能在动画中发生),设置并不断增加X*180度的旋转目标。例如,如果我们需要在视图上旋转鼠标点击:点击->旋转到180->点击->旋转到2 x 180->。。。你明白了。使用LinearInterpolator获得与上一个答案相同的完整答案。但是如何确保每次按下图像时都会发生旋转呢?现在它只发生一次。使用“rotateBy”。参考API,这将是你最喜欢的动画工具。有什么方法可以控制旋转方向吗?我会尝试负值。但我不确定是否以编程方式旋转动画。没有任何解释,也没有任何上下文。
<?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"
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
}
view.animate().setDuration(300).rotationBy(180f).start()
private var angle = 0f

angle += 180f
view.animate().setDuration(300).rotation(angle).start()