1
package com.example.demo;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import android.widget.RelativeLayout;

public class MyLayout extends RelativeLayout {
private static final int INVALID_POINTER_ID = -1;

private Drawable mIcon;
private float mPosX;
private float mPosY;
MyLayout temp;
private float mLastTouchX;
private float mLastTouchY;
private int mActivePointerId = INVALID_POINTER_ID;

private ScaleGestureDetector mScaleDetector;
private float mScaleFactor = 1.f;

public MyLayout(Context context) {
    this(context, null, 0);
    temp = this;
}

public MyLayout(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
    temp = this;
}

public MyLayout(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    mIcon = context.getResources()
            .getDrawable(R.drawable.ic_launcher);
    mIcon.setBounds(0, 0, mIcon.getIntrinsicWidth(),
            mIcon.getIntrinsicHeight());
    temp = this;
    mScaleDetector = new ScaleGestureDetector(context,
            new ScaleListener());
}

@Override
public boolean onTouchEvent(MotionEvent ev) {
    // Let the ScaleGestureDetector inspect all events.

    mScaleDetector.onTouchEvent(ev);

    final int action = ev.getAction();
    switch (action & MotionEvent.ACTION_MASK) {
    case MotionEvent.ACTION_DOWN: {
        final float x = ev.getX();
        final float y = ev.getY();

        mLastTouchX = x;
        mLastTouchY = y;
        mActivePointerId = ev.getPointerId(0);
        break;
    }

    case MotionEvent.ACTION_MOVE: {
        final int pointerIndex = ev
                .findPointerIndex(mActivePointerId);
        final float x = ev.getX(pointerIndex);
        final float y = ev.getY(pointerIndex);

        // Only move if the ScaleGestureDetector isn't processing a
        // gesture.
        if (!mScaleDetector.isInProgress()) {
            final float dx = x - mLastTouchX;
            final float dy = y - mLastTouchY;

            mPosX += dx;
            mPosY += dy;

            invalidate();
        }

        mLastTouchX = x;
        mLastTouchY = y;

        break;
    }

    case MotionEvent.ACTION_UP: {
        mActivePointerId = INVALID_POINTER_ID;

        break;
    }

    case MotionEvent.ACTION_CANCEL: {
        mActivePointerId = INVALID_POINTER_ID;
        break;
    }

    case MotionEvent.ACTION_POINTER_UP: {
        final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
        final int pointerId = ev.getPointerId(pointerIndex);
        if (pointerId == mActivePointerId) {
            // This was our active pointer going up. Choose a
            // new
            // active pointer and adjust accordingly.
            final int newPointerIndex = pointerIndex == 0 ? 1
                    : 0;
            mLastTouchX = ev.getX(newPointerIndex);
            mLastTouchY = ev.getY(newPointerIndex);
            mActivePointerId = ev.getPointerId(newPointerIndex);
        }

        break;
    }
    }
    return true;
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    int count = getChildCount();
    Log.d("onLayout", "" + count);
    for (int i = 0; i < count; i++) {
        View child = getChildAt(i);
        if (child.getVisibility() != GONE) {
            RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) child
                    .getLayoutParams();
            child.layout((int) (params.leftMargin * mScaleFactor),
                    (int) (params.topMargin * mScaleFactor),
                    (int) ((params.leftMargin + child
                            .getMeasuredWidth()) * mScaleFactor),
                    (int) ((params.topMargin + child
                            .getMeasuredHeight()) * mScaleFactor));

            child.setLayoutParams(params);
        }
    }
}

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

    canvas.save(Canvas.MATRIX_SAVE_FLAG);
    // canvas.translate(mLastTouchX, mLastTouchY);
    canvas.translate(mPosX, mPosY);
    canvas.scale(mScaleFactor, mScaleFactor);
    System.out.println("onDraw");
    int count = getChildCount();
    for (int i = 0; i < count; i++) {
        View child = getChildAt(i);
        if (child.getVisibility() != GONE) {
            child.draw(canvas);
            Log.d("onDraw", "" + mScaleFactor);
        }
    }

    canvas.restore();
}

@Override
protected void dispatchDraw(Canvas canvas) {
    canvas.save(Canvas.MATRIX_SAVE_FLAG);
    System.out.println("dispatchDraw");
    System.out.println("x :: " + mPosX + " :: X2 :: " + mLastTouchX);
    System.out.println("y :: " + mPosY + " :: Y2 :: " + mLastTouchY);
    System.out.println("Scale factor :: " + mScaleFactor);
    canvas.translate(
            mPosX
                    - ((mLastTouchX * mScaleFactor) - mLastTouchX),
            mPosY
                    - ((mLastTouchY * mScaleFactor) - mLastTouchY));
    canvas.scale(mScaleFactor, mScaleFactor);

    super.dispatchDraw(canvas);
    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(1.0f, Math.min(mScaleFactor, 5.0f));
        // Log.d("onScale", ""+mScaleFactor);
        temp.invalidate();
        invalidate();
        return true;
    }
}
}

Above code is for custom relative layout for pinch zoom and move with finger on screen.

But, above code is working properly. but problem is that I unable to implement zoom from where I pinch on screen.

Please help me for this.

I took a references from below link.

Zoom and Pinch RelativeLayout

Community
  • 1
  • 1
Komal Sorathiya
  • 228
  • 1
  • 9

0 Answers0