I need to rotate a view which have some buttons. With the finger movement, view should also rotate along with it's child views accordingly.
Till now I have implemented this:
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);
}
But it is not smooth and thus can't be implemented.
Thanks.
First, do not use animation, as you want to directly change the view as the finger moves.
Then, for the computations, it is a lot easier to attach the OnTouchListener to a parent view of the view you want to rotate, so that the coordinate of your touch event is not modified by the rotation itself.
Here is the code if you have a parent view with id "@+id/root":