Extending RelativeLayout, and overriding dispatchDraw() to create a zoomable ViewGroup
If you are applying a scale factor to the drawing of your children, you also need to apply the appropriate scale factor to all of the other interactions with them -- dispatching touch events, invalidates, etc.
So in addition to dispatchDraw(), you will need to override and appropriate adjust the behavior of at least these other methods. To take care of invalidates, you will need to override this method to adjust the child coordinates appropriately:
http://developer.android.com/reference/android/view/ViewGroup.html#invalidateChildInParent(int[], android.graphics.Rect)
If you want the user to be able to interact with the child views you will also need to override this to adjust touch coordinates appropriately before they are dispatched to the children:
http://developer.android.com/reference/android/view/ViewGroup.html#dispatchTouchEvent(android.view.MotionEvent)
Also I would strongly recommend you implement this all inside of a simple ViewGroup subclass that has a single child view it manages. This will get rid of any complexity of behavior that RelativeLayout is introducing in its own ViewGroup, simplifying what you need to deal with and debug in your own code. Put the RelativeLayout as a child of your special zooming ViewGroup.
Finally, one improvement to your code -- in dispatchDraw() you want to save the canvas state after applying the scaling factor. This ensures that the child can't modify the transformation you have set.
Android - zoom in/out RelativeLayout with spread/pinch
So I created a subclass of RelativeLayout
as described in the above mentioned topics. It looks like this:
public class ZoomableRelativeLayout extends RelativeLayout {
float mScaleFactor = 1;
float mPivotX;
float mPivotY;
public ZoomableRelativeLayout(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public ZoomableRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public ZoomableRelativeLayout(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
protected void dispatchDraw(Canvas canvas) {
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.scale(mScaleFactor, mScaleFactor, mPivotX, mPivotY);
super.dispatchDraw(canvas);
canvas.restore();
}
public void scale(float scaleFactor, float pivotX, float pivotY) {
mScaleFactor = scaleFactor;
mPivotX = pivotX;
mPivotY = pivotY;
this.invalidate();
}
public void restore() {
mScaleFactor = 1;
this.invalidate();
}
}
My implementation of the SimpleOnScaleGestureListener
looks like this:
private class OnPinchListener extends SimpleOnScaleGestureListener {
float startingSpan;
float endSpan;
float startFocusX;
float startFocusY;
public boolean onScaleBegin(ScaleGestureDetector detector) {
startingSpan = detector.getCurrentSpan();
startFocusX = detector.getFocusX();
startFocusY = detector.getFocusY();
return true;
}
public boolean onScale(ScaleGestureDetector detector) {
mZoomableRelativeLayout.scale(detector.getCurrentSpan()/startingSpan, startFocusX, startFocusY);
return true;
}
public void onScaleEnd(ScaleGestureDetector detector) {
mZoomableRelativeLayout.restore();
}
}
Hope this helps!
Update:
You can integrate OnPinchListener
for your ZoomableRelativelayout
by using ScaleGestureDetector
:
ScaleGestureDetector scaleGestureDetector = new ScaleGestureDetector(this, new OnPinchListener());
And you are required to bind touch listener of Zoomable layout with the touch listener of ScaleGestureDetector:
mZoomableLayout.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
scaleGestureDetector.onTouchEvent(event);
return true;
}
});
How to zoom ViewGroup?
To zoom view group you need to extend ScrollView and override dispatchTouchEvent and dispatchDraw.
Zooming a layout (Relative Layout) in android
Since no one came up with solution, I kind of sort it out myself and thought it might be helpful for some one else who is stuck in this problem. The basic guidance came from here, where author implemented the zoom in and out for a single image, we just have to add images and handle other initialization as described in that tutorial.
ImageViewWithZoomClass:
private Drawable imageOne, imageTwo;
imageOne = context.getResources().getDrawable(R.drawable.icon1);
imageTwo = context.getResources().getDrawable(R.drawable.icon2);
.
.
imageOne.setBounds(0, 0, imageOne.getIntrinsicWidth(), imageOne.getIntrinsicHeight());
imageTwo.setBounds(0, 0, imageTwo.getIntrinsicWidth(), imageTwo.getIntrinsicHeight());
.
.
imageOne.draw(canvas);
imageTwo.draw(canvas);
and since I am using relative layout, I just used onClickListener in my MainActivity like this
relativeLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
setContentView(new ImageViewWithZoom(getApplicationContext()));
}
});
and XML for the relative layout looks like this:
<RelativeLayout
android:id="@+id/relativeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="130dp"
android:layout_marginRight="130dp"
android:background="@drawable/abc"
android:clickable="true"
android:focusable="true"
android:focusableInTouchMode="true"
>
<ImageView
android:id="@+id/img_1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/roadandrailways"
android:visibility="invisible"/>
<ImageView
android:id="@+id/img_2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/capital"
android:visibility="invisible"/>
</RelativeLayout>
You can add multiple images in layout.
Thats it, hope it helps.
Create a layout larger then screen
Android already comes with a view container that is dedicated to all that scrolling business: ScrollView
.
Related Topics
How to Select Multiple Images from Gallery in Android
How Get Permission for Camera in Android.(Specifically Marshmallow)
Forgot Keystore Password, Thinking of Brute-Force Detection. Will It Corrupt the Keystore
Javadoc in Eclipse Failing to Recognize Packages
Android Webview - Intercept Clicks
List View Items Changes Position When Scrolling Android
Image Size for All Screen Devices
How Can Write Code to Make Sharedpreferences for Array in Android
How to Show and Hide Actionbar with Appcompat V.7
Applying Colorfilter to Imageview with Shapeddrawable
Using Adb Logcat with a Real Phone (And Not the Emulator)
Why Getspeed() Always Return 0 on Android
How to Setlayoutparams() for an Imageview
Bulk Insertion on Android Device
Adding Your Own SQLite Database to an Android Application
Navigation Drawer to Switch Activities Instead of Fragments