我有一個自定義的View,IndicatorView,它基本上是一個三角形,它根據半徑等於三角形長度的半徑的指定角度定向自己。三角形指向的角度經常更新,我想在這兩個位置之間進行動畫處理,類似於時鐘上的一隻手的動作。下面是我的自定義視圖的圖示(未按比例繪製或按比例繪製;繪製根據Android的圖座標面):帶自定義視圖的旋轉動畫
在IndicatorView類,我畫使用Path對象和三個三角形的PointF對象:
@Override
protected void onDraw(Canvas canvas){
path = new Path();
path.setFillType(Path.FillType.EVEN_ODD);
//a, b, and c are PointF objects
path.moveTo(a.x, a.y);
path.lineTo(b.x, b.y);
path.lineTo(c.x, c.y);
path.close();
canvas.drawPath(path, paint);
}
爲了計算不同的點,給定角度,我使用參數方程:
public void showAngle(){
//x = centerX + radius * cos(angle)
//y = centerY + radius * sin(angle)
//TODO sloppy; tidy up/optimize once finished
//centerX, centerY, length, and bottomWidth are all values
//calculated in onSizeChanged
a = new PointF((float) (centerX + (length * Math.cos(angle))), (float) (centerY + (length * Math.sin(angle))));
//perpendicular bilateral radius
double pRadius = bottomWidth/2;
//perpendicular angle plus or minus 90 degrees depending on point
float pAngle = angle - 90;
pAngle = (pAngle < 0) ? 360 - Math.abs(pAngle) : pAngle;
pAngle = (pAngle > 360) ? pAngle % 360 : pAngle;
b = new PointF((float) (centerX + (pRadius * Math.cos(pAngle))), (float) (centerY + (pRadius * Math.sin(pAngle))));
pAngle = angle + 90;
pAngle = (pAngle < 0) ? 360 - Math.abs(pAngle) : pAngle;
pAngle = (pAngle > 360) ? pAngle % 360 : pAngle;
c = new PointF((float) (centerX + (pRadius * Math.cos(pAngle))), (float) (centerY + pRadius * Math.sin(pAngle)));
invalidate();
}
當我有了新角度時,我使用ObjectAnimator在兩個角度之間進行動畫處理。我放在ObjectAnimator的AnimatorUpdateListener並使用從動畫中指定的中間值叫我showAngle()方法在我IndicatorView:
public void updateAngle(float newAngle){
//don't animate to an angle if the previous angle is the same
if(view.getAngle() != newAngle){
if(anim != null && anim.isRunning()){
anim.cancel();
}
anim = ObjectAnimator.ofFloat(view, "angle", view.getAngle(), newAngle);
anim.setDuration(duration);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
if(view != null){
view.showAngle();
}
}
});
}
}
然而,這個代碼將產生一些奇怪和意外的行爲:
- 三角形的寬度大小變化很大。這可能是因爲在不同類型之間進行投射,但不應該那麼戲劇化。
- 三角形的點不會停在指定的角度。相反,它只是繼續前進一圈。
- 角度似乎決定了動畫速度,而不是三角形應該停止的位置。
- 有時看起來屏幕上有許多三角形。這可能是由於速度的原因,也許它的速度非常快。
很明顯,沿線的某處我的計算結果一定是不正確的,儘管如此,我正在努力找出我出錯的地方。 問題:有沒有一種更有效的方式讓我的自定義視圖動畫旋轉到給定的角度?如果我正確地處理這個問題,我會在哪裏出錯?