You can use this approach: calculate radius of inner circle (minimal radius) and then draw circles and increasing radius, while circle can be visible on screen (max radius is not grater than distance from center of screen to one of its corner). Try this custom view with ScaleGestureDetector
:
public class ZoomableRingView extends View {
private Paint mPaint;
private ScaleGestureDetector mScaleDetector;
private float mDeltaRadius = 0;
private final float mBaseRadius = 50;
private float mPinchBaseRadius = mBaseRadius;
private float mMinRadius = mBaseRadius;
public ZoomableRingView(Context context) {
super(context);
init(context);
}
public ZoomableRingView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context);
}
public ZoomableRingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
public ZoomableRingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context);
}
@Override
public void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
canvas.save();
drawCircles(canvas);
canvas.restore();
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
mScaleDetector.onTouchEvent(ev);
return true;
}
private void init(Context context) {
setWillNotDraw(false);
mPaint = new Paint();
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setAntiAlias(true);
mPaint.setColor(Color.RED);
mPaint.setStrokeWidth(5);
mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
}
private void drawCircles(Canvas canvas) {
int canvasWidth = canvas.getWidth();
int canvasHeight = canvas.getHeight();
int centerX = canvasWidth / 2;
int centerY = canvasHeight / 2;
float maxRadius = (float) Math.sqrt(centerX * centerX + centerY * centerY);
int nCircles = (int) Math.ceil(maxRadius / mBaseRadius) + 1;
// calculate radius change
mMinRadius = mPinchBaseRadius + mDeltaRadius / 2;
// bring radius to [0..2 * mBaseRadius] interval
while (mMinRadius < 1f) {
mMinRadius += 2 * mBaseRadius;
}
while (mMinRadius > 2 * mBaseRadius) {
mMinRadius -= 2 * mBaseRadius;
}
// draw circles from min to max
float radius = mMinRadius;
for (int ixCircle = 0; ixCircle < nCircles; ixCircle++) {
canvas.drawCircle(centerX, centerY, radius, mPaint);
radius += 2 * mBaseRadius;
}
}
private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
float startingSpan;
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
mPinchBaseRadius = mMinRadius;
startingSpan = detector.getCurrentSpan();
return true;
}
@Override
public boolean onScale(ScaleGestureDetector detector) {
mDeltaRadius = detector.getCurrentSpan() - startingSpan;
invalidate();
return true;
}
}
}
Your activity.xml
with that custom view can be like:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout_channel1"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<{YOUR_PACKAGE_NAME}.ZoomableRingView
android:id="@+id/zoomablering_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
And you should get something like that:
