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

Android 基于用户拖动事件的动画持续时间,android,animation,rotation,android-animation,Android,Animation,Rotation,Android Animation,我现在正在使用旋转瓶子应用程序,我的瓶子正在旋转,但我希望旋转的速度将基于此事件的用户,并且我希望它在随机位置停止,我可以拖动瓶子,但动画始终从中心开始,在两次旋转后停止在与开始相同的位置 我做错了什么 我的代码: @Override public boolean onTouch(View v, MotionEvent event) { final float xc = bottle.getWidth() / 2; final float yc = bottle.getHei

我现在正在使用旋转瓶子应用程序,我的瓶子正在旋转,但我希望旋转的速度将基于此事件的用户,并且我希望它在随机位置停止,我可以拖动瓶子,但动画始终从中心开始,在两次旋转后停止在与开始相同的位置

我做错了什么

我的代码:

 @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"
    />

我做错了什么

很多事情。F.e.您正在ACTION\u MOVE中实现动画,MotionEvent.ACTION\u取消中实现随机数,另外还有一个额外的xml RotateAimation,您不需要它

我会采取一种完全不同的方法。对于常规动画检出及其方法,这是设置视图动画的最简单方法。以下是一些开始:

旋转连接到触摸事件的瓶子的最小示例:

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;
}
其最小持续时间/轮换开始时间=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和“开始”之间生成一个随机数

这是ViewPropertyAnimator以降低的速度旋转瓶子和生成的随机旋转/持续时间:

bottle.animate()
   .rotation(toDegrees)
   .setInterpolator(new DecelerateInterpolator())
   .setDuration(duration);
这基本上就是你所需要的,只是给你一个想法的替代品,在我看来,更好的方法为未来的动画

我做错了什么

很多事情。F.e.您正在ACTION\u MOVE中实现动画,MotionEvent.ACTION\u取消中实现随机数,另外还有一个额外的xml RotateAimation,您不需要它

我会采取一种完全不同的方法。对于常规动画检出及其方法,这是设置视图动画的最简单方法。以下是一些开始:

旋转连接到触摸事件的瓶子的最小示例:

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;
}
其最小持续时间/轮换开始时间=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和“开始”之间生成一个随机数

这是ViewPropertyAnimator以降低的速度旋转瓶子和生成的随机旋转/持续时间:

bottle.animate()
   .rotation(toDegrees)
   .setInterpolator(new DecelerateInterpolator())
   .setDuration(duration);
这基本上就是你所需要的,只是给你一个想法的替代品,在我看来,更好的方法为未来的动画