所以,我的问题有点类似于这两个问题:
Custom View onDraw is constantly called
android: onDraw is called constantly
我有一个扩展ImageView的自定义类,我将RotateAnimation应用于。动画使用输入x和y坐标执行从最后一个角度到下一个角度的旋转,以便用户可以根据需要将ImageView从-360度旋转到360度。当我将这个代码用于onDraw()时,屏幕上的一切看起来都很完美(动画设置如下面的代码所示):
@Override
protected void onDraw(Canvas canvas) {
Log.d(TAG, "It is drawn again!");
this.setAnimation(anim);
super.onDraw(canvas);
}
问题在于,与上述其他帖子一样,动画调用onDraw调用动画等,可能是通过RotateAnimation类中的invalidate()。这是否正确观察到了?输出是完美的,因为ImageView始终保持当前计算的角度,但动画计算因此继续进行,消耗大量的功率和容量。
为了解决这个问题,我尝试在计算动画参数的方法中移动this.setAnimation(anim)(请忽略isClockWise(),calculateAngleToMove()和其他非Android内容,它们按预期工作) :
private void turnWheel(){
float angle = 0;
if ( isClockWise() ){
angle = calculateAngleToMove();
anim = new RotateAnimation(current_angle, angle, center_x, center_y);
anim.setFillAfter(true);
anim.setFillEnabled(true);
current_angle += angle;
}
else{
angle = - calculateAngleToMove();
anim = new RotateAnimation(current_angle, angle, center_x, center_y);
anim.setFillAfter(true);
anim.setFillEnabled(true);
current_angle += angle;
}
if ( current_angle > 360 ){
current_angle = current_angle - 360;
}
if ( current_angle < -360 ){
current_angle = current_angle + 360;
}
this.setAnimation(anim);
this.invalidate(); //Calls onDraw()
}
这解决了onDraw不断被调用的问题,但它创建了另一个:当用户推动,保持并转动ImageView时,它在零角度和当前角度之间来回捕捉。当用户然后放开ImageView时,它会快速回到零角度。当用户不提供输入时,也希望始终在变量current_angle处旋转ImageView。
我尝试过不同版本的anim.setFillAfter(true),anim.setFillEnabled(true),invalidate()和this.startAnimation(anim),但它们似乎从未对此问题产生任何影响。
调用this.setAnimation(anim)的最佳位置在哪里?
答案 0 :(得分:0)
我可能建议不要使用Animation
框架将静态转换应用于视图,这样您就不必每次都应用新Animation
时处理由重置引起的问题。 / p>
如果您要旋转的内容仅包含图像,请考虑将图像包裹在RotateDrawable
中,并将其设置为ImageView
的内容。通过这种方式,您可以通过设置其级别值(Drawable.setLevel()
或ImageView.setImageLevel()
应该执行操作)来控制可绘制的旋转方式,并且转换将保持不变。如果您需要在一段时间内自动化动画,您只需调用Handler
内的级别设置代码,该代码会经常发布更新。
另一种选择是创建自定义ViewGroup
并使用getChildStaticTransformation()
方法将旋转应用于任何子视图(确保启用它或覆盖已启用它的子类)。 Transformation
是Animation
框架用于修改视图外观的内容。在这种情况下,当用户输入发生变化时,您可能仍需要调用invalidate()
以强制重新绘制。如果您想要定期自动执行更改,则适用相同的Handler
规则。
RotateDrawable示例
假设您要旋转的图像位于res / drawable / wheel.png,在res / drawable / wheel_rotate.xml创建一个简单的XML文件:
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/wheel"
android:fromDegrees="0"
android:toDegrees="360"
android:pivotX="50%"
android:pivotY="50%" />
将图片打包成RotateDrawable
。然后,在您的Java代码集中,可绘制为ImageView
的内容:
ImageView wheel;
//You only do this once
wheel.setImageResource(R.drawable.wheel_rotate);
//Adjust the progress any time you need to by adjusting the drawable's level
wheel.setImageLevel(500);
默认情况下,级别范围为0到10,000。因此映射到0 level = fromDegrees和10,000 level = toDegrees。
HTH