I am implementing scaling functionality inside a custom view on Android, based on the tutorial from here. The scaling feature seems to be working fine, but I am facing an issue where the view moves to the origin (0, 0) when I scale down. I want the view to remain in its original position while scaling.
Here's the code for my custom view:
public class MyCustomView extends View {
private ScaleGestureDetector mScaleDetector;
private float mScaleFactor = 1.0f;
private Paint paint;
public MyCustomView(Context context) {
super(context);
init(context);
}
public MyCustomView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context);
}
public MyCustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
}
@Override
protected void onDraw(Canvas canvas) {
float cx = getWidth()/2f;
float cy = getHeight()/2f;
canvas.save();
canvas.scale(mScaleFactor, mScaleFactor);
canvas.drawRect(cx - 100, cy - 100, cx + 100, cy + 100, paint);
canvas.restore();
}
private class ScaleListener
extends ScaleGestureDetector.SimpleOnScaleGestureListener {
@Override
public boolean onScale(ScaleGestureDetector detector) {
mScaleFactor *= detector.getScaleFactor();
// Don't let the object get too small or too large.
mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 5.0f));
invalidate();
return true;
}
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
// Let the ScaleGestureDetector inspect all events.
mScaleDetector.onTouchEvent(ev);
return true;
}
}
Currently, when I scale down, the rectangle moves to the point (0, 0), instead of remaining at the center of the screen. I want to fix this issue and ensure that the view stays in its original position. How can I do this?
I have attached a GIF that shows the issue:
I guess that's because you are scaling the whole Canvas, doing so it shrinks towards origin (0,0).
canvas.scale(mScaleFactor, mScaleFactor);
You can solve this setting a pivot to the scale, like this as we discussed in the comments
canvas.scale(mScaleFactor, mScaleFactor, cx, cy);