0

I'm trying to make a ScaleAnimation for zooming background and objects (which are located on it) and next change size, position or rotate it using onTouch() conditions.

Example: https://i.stack.imgur.com/UbRxB.jpg

So when I want to make a dragging or zooming any of that objects without a ScaleAnimation it becomes very difficult because objects are too small, instead I want to Scale on 3f the bg and whole group of objects and use onTouch() method to change the objects displaying and Translate animation to move to another object.

My method is wrong because after making this:

iv_object1.setOnTouchListener(this);

AnimationSet set;
Animation scaleToObject;
set = new AnimationSet(true);

int[] xyOfObject = new int[2];
iv_object1.getLocationOnScreen(xyOfObject);

scaleToObject = new ScaleAnimation(
                                1f,
                                3f,
                                1f,
                                3f,
                                xyOfObject[0],
                                xyOfObject[1]
);
set.addAnimation(scaleToObject);
set.setFillAfter(true);
set.setDuration(750);

iv_bg_of_objects.startAnimation(set);
iv_object1.startAnimation(set);
iv_object2.startAnimation(set);
iv_object3.startAnimation(set);
iv_object4.startAnimation(set);

onTouch doesn't work :(

@Override
public boolean onTouch(View v, MotionEvent event) {
    ImageView view = (ImageView) v;
    view.setScaleType(ImageView.ScaleType.MATRIX);
    float scale;

    dumpEvent(event);
    // Handle touch events here...

    switch (event.getAction() & MotionEvent.ACTION_MASK) {

        case MotionEvent.ACTION_DOWN:   // first finger down only
            matrix.set(view.getImageMatrix());
            savedMatrix.set(matrix);
            start.set(event.getX(), event.getY());
            Log.d(TAG, "mode=DRAG"); // write to LogCat
            mode = DRAG;
            lastEvent = null;
            break;

        case MotionEvent.ACTION_POINTER_DOWN: // first and second finger down

            oldDist = spacing(event);
            Log.d(TAG, "oldDist=" + oldDist);
            if (oldDist > 5f) {
                savedMatrix.set(matrix);
                midPoint(mid, event);
                mode = ZOOM;
                Log.d(TAG, "mode=ZOOM");
            }

            lastEvent = new float[4];
            lastEvent[0] = event.getX(0);
            lastEvent[1] = event.getX(1);
            lastEvent[2] = event.getY(0);
            lastEvent[3] = event.getY(1);

            d = rotation(event);

            break;

        case MotionEvent.ACTION_MOVE:

            if (mode == DRAG) {
                matrix.set(savedMatrix);
                matrix.postTranslate(event.getX() - start.x, event.getY() - start.y); // create the transformation in the matrix  of points
            }
            else if (mode == ZOOM && event.getPointerCount() == 2) {
                // pinch zooming
                float newDist = spacing(event);
                Log.d(TAG, "newDist=" + newDist);
                if (newDist > 5f) {
                    matrix.set(savedMatrix);
                    scale = newDist / oldDist; // setting the scaling of the
                    // matrix...if scale > 1 means
                    // zoom in...if scale < 1 means
                    // zoom out
                    matrix.postScale(scale, scale, mid.x, mid.y);
                }
                // Rotation
                if (lastEvent != null) {
                    newRot = rotation(event);
                    float r = newRot - d;

                    matrix.postRotate(r, view.getMeasuredWidth() / 2, view.getMeasuredHeight() / 2);
                }
            }
            break;

        case MotionEvent.ACTION_UP: // first finger lifted

        case MotionEvent.ACTION_POINTER_UP: // second finger lifted

            mode = NONE;
            Log.d(TAG, "mode=NONE");
            lastEvent = null;
            break;
    }

    view.setImageMatrix(matrix); // display the transformation on screen

    return true; // indicate event was handled
}

/*
 * ----------------------------------------------------
 * Method: rotation
 * Parameters: MotionEvent
 * Returns: float
 * Description: rotate
 * ----------------------------------------------------
 */
private float rotation(MotionEvent event) {
    double delta_x = (event.getX(0) - event.getX(1));
    double delta_y = (event.getY(0) - event.getY(1));
    double radians = Math.atan2(delta_y, delta_x);

    return (float) Math.toDegrees(radians);
}

/*
 * --------------------------------------------------------------------------
 * Method: spacing
 * Parameters: MotionEvent
 * Returns: float
 * Description:
 * checks the spacing between the two fingers on touch
 * ----------------------------------------------------
 */
private float spacing(MotionEvent event) {
    float x = event.getX(0) - event.getX(1);
    float y = event.getY(0) - event.getY(1);

    return (float) Math.sqrt(x * x + y * y);
}

/*
 * --------------------------------------------------------------------------
 * Method: midPoint
 * Parameters: PointF object, MotionEvent
 * Returns: void
 * Description: calculates the midpoint between the two fingers
 * ------------------------------------------------------------
 */
private void midPoint(PointF point, MotionEvent event) {
    float x = event.getX(0) + event.getX(1);
    float y = event.getY(0) + event.getY(1);
    point.set(x / 2, y / 2);
}

/** Show an event in the LogCat view, for debugging */
private void dumpEvent(MotionEvent event) {
    String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE","POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" };
    StringBuilder sb = new StringBuilder();
    int action = event.getAction();
    int actionCode = action & MotionEvent.ACTION_MASK;
    sb.append("event ACTION_").append(names[actionCode]);

    if (actionCode == MotionEvent.ACTION_POINTER_DOWN || actionCode == MotionEvent.ACTION_POINTER_UP) {
        sb.append("(pid ").append(action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
        sb.append(")");
    }

    sb.append("[");
    for (int i = 0; i < event.getPointerCount(); i++) {
        sb.append("#").append(i);
        sb.append("(pid ").append(event.getPointerId(i));
        sb.append(")=").append((int) event.getX(i));
        sb.append(",").append((int) event.getY(i));
        if (i + 1 < event.getPointerCount())
            sb.append(";");
    }

    sb.append("]");
    Log.d("Touch Events ---------", sb.toString());
}

Has anyone any suggestions? Thank you!

willford
  • 39
  • 2
  • 9
  • use `MatrixGestureDetector` from [here](https://stackoverflow.com/a/21657145/2252830) and if to want to scale your objects from code simply scale their `Matrix`es – pskink Feb 05 '18 at 20:31
  • ok, pskink. I'm going to try it. – willford Feb 06 '18 at 08:31
  • @pskink, can I use it for scaling background too? – willford Feb 06 '18 at 09:13
  • what background? how do you draw it? – pskink Feb 06 '18 at 09:13
  • the goal is to scale objects together with background because bg has a draw that represents a full image with that objects after scaling it back (to the normal size). – willford Feb 06 '18 at 09:16
  • ok make a custom `BitmapDrawable` class, override `draw()` method, call `super.draw(canvas)` and finally draw your objects, now use that custom `BitmapDrawable` in some `ImageView` by calling `ImageView#setImageDrawable` and if you scale/rotate/translate your custom `BitmapDrawable` your objects will follow it – pskink Feb 06 '18 at 09:21
  • thank you, but it's too difficult to me. – willford Feb 06 '18 at 10:21
  • see https://pastebin.com/raw/xxqBQPgz – pskink Feb 06 '18 at 10:42
  • @pskink, thank you, but I can't run your code – willford Feb 09 '18 at 10:44
  • These arguments are contractions: "matrix -> {" and "(v, event) -> {". Can you please give a full sample? – willford Feb 09 '18 at 13:51

0 Answers0