Zoom images in Sketchware

To zoom images in Sketchware, we can create a new class ZoomableImageView and display the image in it. Follow the steps given below.

1. In the xml page add a LinearV linear1, with width and height as match_parent, and padding 0.

2. Add your image using image manager. For example image plants.

3. Create a new more block extra and put following codes in it.

Copy code
}

public class ZoomableImageView extends ImageView {
    Matrix matrix = new Matrix();
    static final int NONE = 0;
    static final int DRAG = 1;
    static final int ZOOM = 2;
    static final int CLICK = 3;
 
    int mode = NONE;
    PointF last = new PointF();
    PointF start = new PointF();
    float minScale = 1f;
    float maxScale = 4f;
    float[] m;
    float redundantXSpace, redundantYSpace;
    float width, height;
    float saveScale = 1f;
    float right, bottom, origWidth, origHeight, bmWidth, bmHeight;
    ScaleGestureDetector mScaleDetector;
    Context context;
 
    public ZoomableImageView(Context context) {
        super(context);
        super.setClickable(true);
        this.context = context;
        mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
        matrix.setTranslate(1f, 1f);
        m = new float[9];
        setImageMatrix(matrix);
        setScaleType(ScaleType.MATRIX);
 
        setOnTouchListener(new OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    mScaleDetector.onTouchEvent(event);
                    matrix.getValues(m);
                    float x = m[Matrix.MTRANS_X];
                    float y = m[Matrix.MTRANS_Y];
                    PointF curr = new PointF(event.getX(), event.getY());
                    switch (event.getAction()) {
                        case MotionEvent.ACTION_DOWN: last.set(event.getX(), event.getY()); start.set(last); mode = DRAG;
                            break;
 
                        case MotionEvent.ACTION_POINTER_DOWN: last.set(event.getX(), event.getY()); start.set(last);
                            mode = ZOOM;
                            break;
 
                        case MotionEvent.ACTION_MOVE:
                            if (mode == ZOOM || (mode == DRAG && saveScale > minScale)) {
                                float deltaX = curr.x - last.x;
                                float deltaY = curr.y - last.y;
                                float scaleWidth = Math.round(origWidth * saveScale);
                                float scaleHeight = Math.round(origHeight * saveScale);
                                if (scaleWidth < width) {
                                    deltaX = 0;
                                    if (y + deltaY > 0) deltaY = -y;
                                    else if (y + deltaY < -bottom) deltaY = -(y + bottom);
                                } else if (scaleHeight < height) {
                                    deltaY = 0;
                                    if (x + deltaX > 0) deltaX = -x;
                                    else if (x + deltaX < -right) deltaX = -(x + right);
                                } else {
                                    if (x + deltaX > 0) deltaX = -x;
                                    else if (x + deltaX < -right) deltaX = -(x + right);
                                    if (y + deltaY > 0) deltaY = -y;
                                    else if (y + deltaY < -bottom) deltaY = -(y + bottom);
                                }
                                matrix.postTranslate(deltaX, deltaY);
                                last.set(curr.x, curr.y);
                            }
                            break;
 
                        case MotionEvent.ACTION_UP:
                            mode = NONE;
                            int xDiff = (int) Math.abs(curr.x - start.x);
                            int yDiff = (int) Math.abs(curr.y - start.y);
                            if (xDiff < CLICK && yDiff < CLICK) performClick();
                            break;
 
                        case MotionEvent.ACTION_POINTER_UP:
                            mode = NONE;
                            break;
                    }
                    setImageMatrix(matrix);
                    invalidate();
                    return true;
                }
            });
    }
 
    @Override
    public void setImageBitmap(Bitmap bm) {
        super.setImageBitmap(bm);
        bmWidth = bm.getWidth();
        bmHeight = bm.getHeight(); }
 
    public void setMaxZoom(float x) {
        maxScale = x; }
 
    private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
        @Override
        public boolean onScaleBegin(ScaleGestureDetector detector) {        
            mode = ZOOM;
            return true;}
 
        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            float mScaleFactor = detector.getScaleFactor();
            float origScale = saveScale;
            saveScale *= mScaleFactor;
            if (saveScale > maxScale){
                saveScale = maxScale;
                mScaleFactor = maxScale / origScale;
            } else if (saveScale < minScale) {   
                saveScale = minScale;
                mScaleFactor = minScale / origScale;}
            right = width * saveScale - width - (2 * redundantXSpace * saveScale);
            bottom = height * saveScale - height - (2 * redundantYSpace * saveScale);
            if (origWidth * saveScale <= width || origHeight * saveScale <= height) {
                matrix.postScale(mScaleFactor, mScaleFactor, width / 2, height / 2);
                if (mScaleFactor < 1) {  
                    matrix.getValues(m);
                    float x = m[Matrix.MTRANS_X];
                    float y = m[Matrix.MTRANS_Y];
                    if (mScaleFactor < 1) {
                        if (Math.round(origWidth * saveScale) < width) {
                            if (y < -bottom) matrix.postTranslate(0, -(y + bottom));
                            else if (y > 0) matrix.postTranslate(0, -y);             
                        } else {
                            if (x < -right) matrix.postTranslate(-(x + right), 0);
                            else if (x > 0) matrix.postTranslate(-x, 0);}                
                    }               
                }       
            } else {
                matrix.postScale(mScaleFactor, mScaleFactor, detector.getFocusX(), detector.getFocusY()); matrix.getValues(m);
                float x = m[Matrix.MTRANS_X];   
                float y = m[Matrix.MTRANS_Y];
                if (mScaleFactor < 1) {
                    if (x < -right) matrix.postTranslate(-(x + right), 0);   
                    else if (x > 0) matrix.postTranslate(-x, 0);
                    if (y < -bottom) matrix.postTranslate(0, -(y + bottom));         
                    else if (y > 0) matrix.postTranslate(0, -y);}            
            }
            return true;            
        }       
    }
 
    @Override
    protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width = MeasureSpec.getSize(widthMeasureSpec);
        height = MeasureSpec.getSize(heightMeasureSpec);
        float scale;
        float scaleX = width / bmWidth;
        float scaleY = height / bmHeight;
        scale = Math.min(scaleX, scaleY); matrix.setScale(scale, scale); setImageMatrix(matrix);
        saveScale = 1f;
        redundantYSpace = height - (scale * bmHeight) ;
        redundantXSpace = width - (scale * bmWidth);
        redundantYSpace /= 2;
        redundantXSpace /= 2; matrix.postTranslate(redundantXSpace, redundantYSpace);
        origWidth = width - 2 * redundantXSpace;
        origHeight = height - 2 * redundantYSpace;
        right = width * saveScale - width - (2 * redundantXSpace * saveScale);
        bottom = height * saveScale - height - (2 * redundantYSpace * saveScale);
        setImageMatrix(matrix);
    }
}

{

4. In onCreate event, create a new ZoomableImageView and add it to linear1. Display the image in the ZoomableImageView. Use following codes.

Copy code
ZoomableImageView myimageview = new ZoomableImageView(this);
myimageview.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
Bitmap myimage = BitmapFactory.decodeResource(getResources(), R.drawable.plants);
myimageview.setImageBitmap(myimage);
linear1.addView(myimageview);

5. Save and run the project.

Comments

  1. Sir how to set zoomable image from image url link.

    ReplyDelete
  2. Bro but double tap does not get the image back to normal after zooming, if u could do something for that it would be great

    ReplyDelete

Post a Comment

Popular posts from this blog

Create Music Player app in Sketchware

A Flash Light App in Sketchware

Admob rewarded video Ads in Sketchware

Simple car racing android game in Sketchware

Firebase auth in Sketchware for Login Activity