Mert Serimer Mert Serimer - 1 month ago 15
Android Question

Android Canvas How to achieve Continous Smooth Motion(Rotation)

My problem is, i am trying to rotate a canvas around a certain point smoothly and continously. The problem is, it does not look smooth. Here is my code below;

rotateRunnable.run();
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
rect.set(xLeft, yTop, xRight, yBottom);
paint.setColor(color);
if(rotate)
canvas.rotate(rotateAngle,CoordinateUtils.centerX,CoordinateUtils.centerY);
canvas.drawRect(rect,paint);

}

Handler handler = new Handler(Looper.getMainLooper());
Runnable rotateRunnable = new Runnable(){
public void run(){
if(rotateReverse)
rotateAngle = rotateAngle - DValues.markerSpeed;
else
rotateAngle = rotateAngle + DValues.markerSpeed;
postInvalidate(); //will trigger the onDraw
handler.postDelayed(this,1); //
}};


Is it good idea to translate views in thread? How to achieve continous smooth motion? Also where should i check collision detection with another view object? OnDraw or somewhere else?

Answer

I think the issue is you're calling the Handler every 1 millisecond, so you're just calling this method constantly. Instead, since the logic is very simple and easy, it may better to move it to the onDraw() method. Then call invalidate() on the View. Then, all the calculations will be done every draw cycle.

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    if(rotateReverse)
       rotate = rotate - DValues.markerSpeed;
    else
       rotate = rotate + DValues.markerSpeed;

    rect.set(xLeft, yTop, xRight, yBottom);
    paint.setColor(color);
    canvas.rotate(rotate,CoordinateUtils.centerX,CoordinateUtils.centerY);
    canvas.drawRect(rect,paint);

    invalidate(); //will trigger the onDraw
}

So this will tell the system to perform another draw to update the View. It will only call invalidate() on draw cycles. If the phone is still drawing at 60 fps, then the rotate will be called 60 times a second, so you may need to adjust the speed (possibly base it off the pixel density of the phone). You will also need to base the rotate distance based on where it should be based off how long it was since the last draw cycle (in case the UI froze).