2016-02-01 3 views
1

Теперь я работаю над приложением 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

Что я делаю неправильно?

Многие вещи. F.E. Вы реализуете свою анимацию в ACTION_MOVE, случайные числа в MotionEvent.ACTION_CANCEL, плюс у вас есть дополнительный xml RotateAnimation, который вам не нужен.

Здесь я бы пошел совсем по-другому. Для общей анимации проверьте ViewPropertyAnimator и его методы, это самый простой способ для анимации Views. Heres что-то, чтобы начать с:

Minimal например для прядения вашей бутылки подключена к сенсорному Событию:

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

Thats в основном все, что вам нужно, и просто чтобы дать вам представление о качестве альтернативы, и на мой взгляд, лучший подход для будущих анимаций.

Смежные вопросы