Rotate view using touch motion event and giving it an initial velocity to rotate itself

495 Views Asked by At

I want to rotate an imageview by using users motion event and then the image must keep on rotating with a decelerating angular velocity. I was able to rotate the imageview using ontouchlistener. Then I tried to compute the velocity of the view and added it to the view animation but unfortunately the app crashes in the latter stage. The velocity part is not complete in this code but I don't understand how to implement this part. Please Help!!! Here's my code

public class MainActivity extends Activity implements OnTouchListener {

private static Bitmap imageOriginal;
private static Matrix matrix;

private ImageView bottle;

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    if (imageOriginal == null) {
        imageOriginal = BitmapFactory.decodeResource(getResources(),
                R.drawable.bottle);
    }

    if (matrix == null) {
        matrix = new Matrix();
    } else {
        matrix.reset();
    }

    bottle = (ImageView) findViewById(R.id.bottle_image);
    bottle.setOnTouchListener(this);

}

private double startAngle, currentAngle;
private VelocityTracker vTracker = null;

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

    switch (event.getActionMasked()) {

    case MotionEvent.ACTION_DOWN:
        if (vTracker == null) {
            vTracker = VelocityTracker.obtain();
        } else {
            vTracker.clear();
        }
        vTracker.addMovement(event);
        startAngle = getAngle(event.getY(), event.getX());
        break;

    case MotionEvent.ACTION_MOVE:
        vTracker.addMovement(event);
        vTracker.computeCurrentVelocity(1000);
        currentAngle = getAngle(event.getY(), event.getX());
        rotateBottle(startAngle, currentAngle);
        startAngle = currentAngle;
        break;

    case MotionEvent.ACTION_UP:
        break;

    }
    return true;
}

private double getAngle(double x1, double y1) {
    double x = x1 - (bottle.getWidth() / 2);
    double y = bottle.getHeight() - y1 - (bottle.getHeight() / 2);
    switch (getQuadrant(x, y)) {
    case 1:
        return Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI;
    case 2:
        return 180 - Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI;
    case 3:
        return 180 + (-1 * Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI);
    case 4:
        return 360 + Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI;
    default:
        return 0;
    }
}

private int getQuadrant(double x, double y) {
    if (x >= 0)
        return y >= 0 ? 1 : 4;
    else
        return y >= 0 ? 2 : 3;
}

private void rotateBottle(double start, double end) {
    final RotateAnimation rotate = new RotateAnimation((float) start,
            (float) end, RotateAnimation.RELATIVE_TO_SELF, 0.5f,
            RotateAnimation.RELATIVE_TO_SELF, 0.5f);
    rotate.setDuration(0);
    rotate.setFillEnabled(true);
    rotate.setFillAfter(true);
    bottle.startAnimation(rotate);
}

}

0

There are 0 best solutions below