2013-12-24 4 views
3

Мне нужно повернуть вид, который имеет несколько кнопок. При движении пальца вид также должен вращаться вместе с его детскими видами соответственно.Android: Как повернуть взгляд одним пальцем

До сих пор я реализовал это:

private RelativeLayout mCircle; 
private double mCurrAngle = 0; 
private double mPrevAngle = 0; 
int i = 0; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    mCircle = (RelativeLayout) findViewById(R.id.circle); 
    mCircle.setOnTouchListener(this); // Your activity should implement 
             // OnTouchListener 
} 

@Override 
public boolean onTouch(View v, MotionEvent event) { 
    final float xc = mCircle.getWidth()/2; 
    final float yc = mCircle.getHeight()/2; 

    final float x = event.getX(); 
    final float y = event.getY(); 

    switch (event.getAction()) { 
    case MotionEvent.ACTION_DOWN: { 
     mCircle.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)); 
     mCircle.setRotation((float) (mPrevAngle - mCurrAngle));   

     animate(mPrevAngle, mCurrAngle, 0); 
     break; 
    } 
    case MotionEvent.ACTION_UP: { 
     mPrevAngle = mCurrAngle = 0; 
     break; 
    } 
    } 

    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); 
    mCircle.startAnimation(rotate); 
} 

Но это не является гладким и, следовательно, не могут быть реализованы.

Спасибо.

ответ

2

Во-первых, не используйте анимацию, так как вы хотите напрямую изменить представление при перемещении пальца.

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

Вот код, если у Вас есть родительское представление с идентификатором «@ + ид/корень»:

private RelativeLayout mRoot; 
private RelativeLayout mCircle; 
int i = 0; 
float viewRotation; 
double fingerRotation; 
double newFingerRotation; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    mRoot = (RelativeLayout)findViewById(R.id.root); 
    mCircle = (RelativeLayout) findViewById(R.id.circle); 
    mRoot.setOnTouchListener(this); 
} 

@Override 
public boolean onTouch(View v, MotionEvent event) { 

    final float x = event.getX(); 
    final float y = event.getY(); 

    final float xc = mRoot.getWidth()/2; 
    final float yc = mRoot.getHeight()/2; 

    switch (event.getAction()) { 
     case MotionEvent.ACTION_DOWN: 
      viewRotation = mCircle.getRotation(); 
      fingerRotation = Math.toDegrees(Math.atan2(x - xc, yc - y)); 
      break; 
     case MotionEvent.ACTION_MOVE: 
      newFingerRotation = Math.toDegrees(Math.atan2(x - xc, yc - y)); 
      mCircle.setRotation((float)(viewRotation + newFingerRotation - fingerRotation)); 
      break; 
     case MotionEvent.ACTION_UP: 
      fingerRotation = newFingerRotation = 0.0f; 
      break; 
    } 

    return true; 
} 
+0

Я попытался с помощью вращения, но до какой степени я должен вращаться? Он становится испорченным, когда я использую 'mCurrAngle' –

+0

Извините, теперь я лучше понимаю ваш код. Посмотрите мои изменения –

+0

Еще не работает –

0
 @Override 
     public boolean onTouch(View view, MotionEvent event) { 

      switch (action) { 
        case MotionEvent.ACTION_UP: 
         break; 
        case MotionEvent.ACTION_DOWN: 

         rotateX = event.getRawX(); 
         rotateY = event.getRawY(); 

         centerX = view.getX() + ((View) getParent()).getX() + (float) view.getWidth()/2; 

         centerY = view.getY() + statusBarHeight + (float) view.getHeight()/2; 

         break; 

        case MotionEvent.ACTION_MOVE: 

         newRotateX = event.getRawX(); 
         newRotateY = event.getRawY(); 

         double angle = Math.atan2(event.getRawY() - centerY, event.getRawX() - centerX) * 180/Math.PI; 

         view.setRotation((float) angle - 45); 

         rotateX = newRotateX; 
         rotateY = newRotateY; 
       } 
      } 

      return true; 
     } 
    };