我现在在SpinTheBottle应用程序上工作,我的瓶子正在旋转,但我希望旋转的速度将基于用户onTouch事件,我希望它在随机位置停止,我可以拖动瓶子但是动画总是从中心开始,经过2次旋转后停在与开头相同的位置。
我做错了什么?
我的代码:
@Override
public boolean onTouch(View v, MotionEvent event) {
final float xc = bottle.getWidth() / 2;
final float yc = bottle.getHeight() / 2;
final float x = event.getX();
final float y = event.getY();
switch (event.getAction()){
case MotionEvent.ACTION_DOWN: {
bottle.clearAnimation();
mCurrAngle = Math.toDegrees(Math.atan2( x - xc, yc - y));
break;
}case MotionEvent.ACTION_MOVE: {
mPrevAngle = mCurrAngle;
mCurrAngle = Math.toDegrees(Math.atan2(x - xc, yc - y));
animate(mPrevAngle, mCurrAngle, 0);
System.out.println(mCurrAngle);
break;
}case MotionEvent.ACTION_CANCEL: {
mPrevAngle = mCurrAngle = 0;
float toDegrees = new Random().nextFloat() * Integer.MAX_VALUE % 360;
final Animation animRotate = AnimationUtils.loadAnimation(this, R.anim.mainanim);
animRotate.setDuration(1000);
animRotate.setRepeatCount(1);
animRotate.setFillAfter(true);
bottle.startAnimation(animRotate);
break;
}case MotionEvent.ACTION_UP:{
}
}
return true;
}
private void animate(double fromDegrees, double toDegrees, long durationMillis){
final RotateAnimation rotate = new RotateAnimation((float) fromDegrees, (float) toDegrees,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
rotate.setDuration(durationMillis);
rotate.setFillEnabled(true);
rotate.setFillAfter(true);
bottle.startAnimation(rotate);
System.out.println(mCurrAngle);
}
动画布局:
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:fromDegrees="0"
android:toDegrees="360"
android:drawable="@drawable/campari"
android:duration="2500"
android:fillAfter="true"
android:fillBefore="true"
android:fillEnabled="true"
android:repeatCount="1"
/>
答案 0 :(得分:0)
我做错了什么?
很多事情。 F.E.您正在ACTION_MOVE中实现动画,在MotionEvent.ACTION_CANCEL中实现随机数,此外还有一个额外的xml RotateAnimation,您不需要它。
我会在这里采用一种截然不同的方法。对于一般动画,请查看ViewPropertyAnimator及其方法,这是动画视图的最简单方法。下面是一些事情:
旋转连接到触摸事件的瓶子的最小示例:
int start = 1000;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
start = 1000;
break;
case MotionEvent.ACTION_MOVE:
start = start + 250;
break;
case MotionEvent.ACTION_UP:
Random random = new Random();
int toDegrees = random.nextInt(start);
int duration = random.nextInt(start + 1000);
bottle.animate()
.rotation(toDegrees)
.setInterpolator(new DecelerateInterpolator())
.setDuration(duration);
break;
}
return true;
}
这具有start = 1000的最小持续时间/旋转; :
case MotionEvent.ACTION_DOWN:
start = 1000;
break;
,你在屏幕上移动的时间越长,开始的时间越长,持续时间/轮换时间越长:
case MotionEvent.ACTION_MOVE:
start = start + 250;
break;
然后当你放开屏幕时,创建随机数:
case MotionEvent.ACTION_UP:
Random random = new Random();
int toDegrees = random.nextInt(start);
int duration = random.nextInt(start + 1000);
它会在0和'start'之间生成一个随机数。
这是ViewPropertyAnimator以降低的速度旋转你的瓶子并产生随机旋转/持续时间:
bottle.animate()
.rotation(toDegrees)
.setInterpolator(new DecelerateInterpolator())
.setDuration(duration);
这基本上就是你所需要的,只是为了让你了解另一种选择,并且在我看来,这是一种更好的未来动画方法。