0

My goal is to create a pinch to zoom edittext.

After some googling, someone kind enough to share this class on github:

public ZoomEditTextView(Context context, AttributeSet attrs) {
    super(context, attrs, 0);
    this.mContext = context;
    init();

}

public ZoomEditTextView(Context context) {
    super(context, null, 0);
    this.mContext = context;
    init();

    setFocusable(true);
    requestFocus();

    /*@formatter:off
    this.setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent me) {

            InputMethodManager imm = (InputMethodManager) mContext.getSystemService(mContext.INPUT_METHOD_SERVICE);
            imm.showSoftInput(v, InputMethodManager.SHOW_IMPLICIT);

            return true;
        }

    });*/

}

private void init() {

    // Create our ScaleGestureDetector
    mScaleDetector = new ScaleGestureDetector(mContext, new ScaleListener());

    // Sets up drawing tools
    mPath = new Path();
    mBitmapPaint = new Paint(Paint.DITHER_FLAG);
    mCirclePaint = new Paint();
    mCirclePath = new Path();
    mCirclePaint.setAntiAlias(true);
    mCirclePaint.setColor(Color.CYAN);
    mCirclePaint.setStyle(Paint.Style.STROKE);
    mCirclePaint.setStrokeJoin(Paint.Join.MITER);
    mCirclePaint.setStrokeWidth(4f);

    //

    mDrawingPaint = new Paint();

    mDrawingPaint.setAntiAlias(true);
    mDrawingPaint.setDither(true);
    mDrawingPaint.setColor(Color.GREEN);
    mDrawingPaint.setStyle(Paint.Style.STROKE);
    mDrawingPaint.setStrokeJoin(Paint.Join.ROUND);
    mDrawingPaint.setStrokeCap(Paint.Cap.ROUND);
    mDrawingPaint.setStrokeWidth(mBrushSize);

    mRectPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mRectPaint.setStyle(Paint.Style.STROKE);
    mRectPaint.setColor(Color.WHITE);

    mDrawable = mContext.getResources().getDrawable(R.drawable.icon);
    mDrawable.setBounds(0, 0, mDrawable.getIntrinsicWidth(), mDrawable.getIntrinsicHeight());
    setDrawingCacheEnabled(true);
    buildDrawingCache();

}

@Override
protected void onDraw(Canvas canvas) {

    canvas.save();
    //
    canvas.translate(mPosX, mPosY);
    canvas.scale(mScaleFactor, mScaleFactor);
    // canvas.drawRect(new Rect(0, 0, canvas.getWidth(),
    // canvas.getHeight()), mRectPaint);

    super.onDraw(canvas);

    // mDrawable.draw(canvas);
    // if (mBitmap != null && canvas != null) {
    // canvas.drawBitmap(mBitmap, mPosX, mPosY, mPaint);
    // }

    canvas.restore();

}

// Listen for multi-touch drag event and redraw the view accordingly
@Override
public boolean onTouchEvent(MotionEvent event) {
    // Let the ScaleGestureDetector inspect all events.
    mScaleDetector.onTouchEvent(event);

    final int action = event.getAction();
    switch (action) {

    // a touch down
        case MotionEvent.ACTION_DOWN: {
            // Scale detector is not in progress
            if (!mScaleDetector.isInProgress()) {
                final float x = event.getX();
                final float y = event.getY();
                // Save the ID of this pointer
                mActivePointerId = event.getPointerId(0);

                // Remember where we started
                mLastTouchX = x;
                mLastTouchY = y;

                // Save the ID of this pointer
                mActivePointerId = event.getPointerId(0);

                break;

            }
        }

        case MotionEvent.ACTION_MOVE: {

            // Only move the image if the scale detector is not in progress
            if (!mScaleDetector.isInProgress()) {
                // Find the index of active pointer and save its position
                final int pointerIndex = event.findPointerIndex(mActivePointerId);
                final float x = event.getX(pointerIndex);
                final float y = event.getY(pointerIndex);

                // mBitmap = getDrawingCache();

                // Calculate the distance moved
                float dx = x - mLastTouchX;
                float dy = y - mLastTouchY;

                // Move the object
                mPosX += dx;
                mPosY += dy;

                // Remember this touch position for the next move event
                mLastTouchX = x;
                mLastTouchY = y;

                // Invalidate to request a redraw
                invalidate();

                // break;

            } /*
               * else {
               * 
               * final float gx = mScaleDetector.getFocusX(); final float gy
               * = mScaleDetector.getFocusY();
               * 
               * final float gdx = gx - mLastGestureX; final float gdy = gy
               * - mLastGestureY;
               * 
               * mPosX += gdx; mPosY += gdy;
               * 
               * invalidate();
               * 
               * mLastGestureX = gx; mLastGestureY = gy;
               * 
               * }
               */

            break;
        }

        case MotionEvent.ACTION_UP: {
            //setFocusable(true);
            //requestFocus();

            InputMethodManager imm = (InputMethodManager) mContext.getSystemService(mContext.INPUT_METHOD_SERVICE);
            //imm.showSoftInput(ZoomEditTextView.this, InputMethodManager.SHOW_IMPLICIT);
            imm.toggleSoftInput(0, InputMethodManager.SHOW_IMPLICIT);

            // Reset the active pointer id
            mActivePointerId = INVALID_POINTER_ID;

            break;
        }

        case MotionEvent.ACTION_CANCEL: {

            mActivePointerId = INVALID_POINTER_ID;
            break;

        }

        case MotionEvent.ACTION_POINTER_UP: {
            // Extract the index of the pointer that left the touch sensor
            final int pointerIndex = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
            final int pointerId = event.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;

                if (event.getPointerCount() >= 2) {
                    mLastTouchX = event.getX(newPointerIndex);
                    mLastTouchY = event.getY(newPointerIndex);
                }
                mActivePointerId = event.getPointerId(newPointerIndex);

            } else {
                final int tempPointerIndex = event.findPointerIndex(mActivePointerId);
                mLastTouchX = event.getX(tempPointerIndex);
                mLastTouchY = event.getY(tempPointerIndex);
            }
            break;

        }

    }

    return true;
}

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;
    }
}

The class is working perfectly for "drag and drop" and "pinch to zoom", but the edittext cant be edited. The keyboard is shown, but the edittext is not focused so i cant type anything.

The editing part is on this code :

    case MotionEvent.ACTION_UP: {
        //setFocusable(true);
        //requestFocus();

        InputMethodManager imm = (InputMethodManager) mContext.getSystemService(mContext.INPUT_METHOD_SERVICE);
        //imm.showSoftInput(ZoomEditTextView.this, InputMethodManager.SHOW_IMPLICIT);
        imm.toggleSoftInput(0, InputMethodManager.SHOW_IMPLICIT);

        // Reset the active pointer id
        mActivePointerId = INVALID_POINTER_ID;

        break;
    }

Please help me and just tell me if you have more question. Thanks

Blaze Tama
  • 10,828
  • 13
  • 69
  • 129
  • check this please http://stackoverflow.com/a/20673915/3020568 – Deniz Jul 07 '14 at 05:19
  • My problem is the un-editable edittext, the pinch 2 zoom is working perfecyly. Thanks – Blaze Tama Jul 07 '14 at 06:15
  • Hi @BlazeTama, can you share you XML where your EditText is located? I will look into it – Jade Byfield Jul 08 '14 at 14:59
  • @JadeByfield sorry for the long response. I have solved this problem for now, but i have a little more problem. Now i try to create a button that will following your edittext. So the button will always be in the bottom right corner of the edittext. Is it possible? Could you show me the way to do it? Thanks a lot :D – Blaze Tama Jul 10 '14 at 04:12
  • @JadeByfield my current problem is your edittext's width & height should be match_parent, so the button will be out of the screen. – Blaze Tama Jul 10 '14 at 05:32

2 Answers2

2

link is here: android pinch zoom

Community
  • 1
  • 1
Dinesh R Rajput
  • 732
  • 8
  • 22
0

Just change setFocusable(true); to setFocusableInTouchMode(true);. Its working but not perfect yet. You cant tap freely inside your edittext, but the edittext is editable with this.

Blaze Tama
  • 10,828
  • 13
  • 69
  • 129