2

I have my application for Android 2.1 where I have a root layout with children's that I can click, move and zoom. Everything is fine, as long as the root layout is not zoomed.

I have a setup like this;

<ZoomableRelativeLayout ...>  // Root, Moveable and zoomable
    <ImageView ....>
    <RelativeLayout ...> // Clickable, moveable and zoomable
    <RelativeLayout ...> // Clickable, moveable and zoomable
</ZoomableRelativeLayout>

And I like to zoom the content in my ZoomableRelativeLayout. I zoom my content like this in my ZoomableRelativeLayout class;

protected void dispatchDraw(Canvas canvas) {
    canvas.save(Canvas.MATRIX_SAVE_FLAG);
    canvas.scale(mScaleFactor, mScaleFactor, mXPointCenter, mYPointCenter);
    super.dispatchDraw(canvas);
    canvas.restore();
}

I get the Zoom result I want, but the problem is then I want to click on the Childviews to ZoomableRelativeLayout when canvas is scaled..

When scale is 1 (no zoom) the interaction with child views is fine, but as zoom as I zoom, its just like the touch area is translated or something, because I can't click them anymore.

How do I fix this? I tried to override onMeasure in ZoomableRelativeLayout like this;

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    setMeasuredDimension((int) (widthSize * mScaleFactor), (int) (heightSize * mScaleFactor));
}

Please help me if anyone can!


Ok, so I changed from using Matrix and using canvas scale to following;

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    final int count = getChildCount();
    for (int i = 0; i < count; i++) {
        final View child = getChildAt(i);
        if (child.getVisibility() != View.GONE) {
            child.layout((int) mPosX, (int) mPosY, (int) (mPosX + getWidth()), (int) (mPosY + getHeight()));
        }
    }
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    setMeasuredDimension((int) (widthSize * mScaleFactor), (int) (heightSize * mScaleFactor));
}

I still have my setup;

<ZoomableRelativeLayout ...>  // Root, Moveable and zoomable
    <ImageView ....>
    <RelativeLayout ...> // Clickable, moveable and zoomable
    <RelativeLayout ...> // Clickable, moveable and zoomable
</ZoomableRelativeLayout>

I can move around the layout and everything is fine, but when I zoom, the RelativeLayouts that is children's of ZoomableRelativeLayout doesnt gets zoomed.. How can I fix this? Do I have to subclass the RelativeLayouts and override onMeasure() or onLayout() or anything?

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
user688291
  • 83
  • 3
  • 11

1 Answers1

2

What you're doing in your dispatchDraw(), is actually just zooming the drawing of the view, and not the view itself. The location and size of the view (left, top, right, bottom) is still the same, although you see the view's drawing in the canvas is zooming. Try this: zoom your ZoomRelativeLayoutjust a little bit, and then interact with the children in their original (non-zoom) location, and see whether the children reacts.

To really zoom a view/viewgroup, you need to transform the actual view, and not only the drawing, i.e. transform the (l,t,r,b) of the view, then requestLayout() invalidate(), but this might hit on the performance.

Ricky Lee
  • 1,039
  • 6
  • 6
  • Hi Ricky, yea I can interact with the children on their original location. Do I have to translate the location of MotionEvent somehow? I also tried another way, to build a Matrix (translate and scale) in my onTouchEvent and just canvas.setMatrix in my draw. How can I transfer the (l,t,r,b) in a correct way? Have searched for examples out there but haven't found any useful :( – user688291 Feb 09 '12 at 06:39
  • 1
    In your `onTouchEvent()` you need to calculate the new (l,t,r,b) based on the scale factor. And then layout the children with the new dimension. You no longer need to set the `canvas.setMatrix()`, because you're now zooming/manipulating the actual view, not the drawing canvas. – Ricky Lee Feb 09 '12 at 08:59
  • What would you suggest to transform l,t,r,b of the view? I'm using the dispatchDraw method too. – edoardotognoni May 27 '14 at 15:17
  • @RickyLee could you please give us a snippet on how to achieve this? I have the same problem here. I'm using this ZoomView: https://github.com/Polidea/android-zoom-view/blob/master/src/pl/polidea/view/ZoomView.java – edoardotognoni May 27 '14 at 16:03