基于用户拖动事件的动画持续时间

时间:2016-02-01 23:03:59

标签: android animation rotation android-animation

我现在在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"
    />

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

这基本上就是你所需要的,只是为了让你了解另一种选择,并且在我看来,这是一种更好的未来动画方法。