I have certain data in placed in my ScrollView
. I want to enable it to zoom in/ zoom out. It contains simple ImageView
and TextView
.
Any suggestions will be helpful.
Thank you.
Here is my code:
<ScrollView
android:id="@+id/viewSoupMenu"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/soupback" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="50dp">
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="35dp"
android:layout_marginTop="30dp"
android:background="@android:color/transparent"
android:src="@drawable/flowericon" />
<ImageButton
android:id="@+id/btnVegClearSoup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginTop="20dp"
android:background="@android:color/transparent"
android:src="@drawable/btnvegsoupclearclickedxml" />
</LinearLayout>
</ScrollView>
You can use the class mentioned below for enabling Pinch Zoom in your ImageView
and you can create a duplicate class of this class which extends TextView
instead of ImageView
for enabling zooming in it.
public class PinchZoomImageView extends ImageView implements OnTouchListener{
public PinchZoomImageView(Context context) {
super(context);
_init();
}
public PinchZoomImageView(Context context, AttributeSet attrs) {
super(context, attrs);
_init();
}
public PinchZoomImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
_init();
}
private void _init(){
//setOnTouchListener(this);
view = (ImageView) this;
view.setOnTouchListener(this);
metric = new DisplayMetrics();
// Work around a Cupcake bug
d_dpi=((0.52f/(metric.densityDpi))*240.0f)-0.52f;
Log.d("ash","dpi= "+d_dpi);
if(metric.densityDpi==160)
d_dpi=0.34f;
matrix.setTranslate(1f, 1f);
matrix.setScale((0.52f/800.0f)*metric.widthPixels+d_dpi, (0.52f/480.0f)*metric.heightPixels+d_dpi);
view.setImageMatrix(matrix);
bMap = BitmapFactory.decodeResource(getResources(), R.drawable.mfigure);
btsize = BitmapFactory.decodeResource(getResources(), R.drawable.map);
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if(hasFocus){
init();
}
}
private void init() {
maxZoom = (3.0f/480.0f)*metric.heightPixels+d_dpi;
minZoom = (0.52f/800.0f)*metric.widthPixels+d_dpi;
height = view.getDrawable().getIntrinsicHeight();
width = view.getDrawable().getIntrinsicWidth();
viewRect = new RectF(0, 0, view.getWidth(), view.getHeight());
}
@Override
public boolean onTouch(View v, MotionEvent event) {
ImageView view = (ImageView) v;
// Handle touch events here...
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
savedMatrix.set(matrix);
start.set(event.getX()/metric.widthPixels * 800, event.getY()/metric.heightPixels * 480);
Log.d(TAG, "mode=DRAG");
mode = DRAG;
click = true;
break;
case MotionEvent.ACTION_POINTER_DOWN:
oldDist = spacing(event);
Log.d(TAG, "oldDist=" + oldDist);
if (oldDist > 10f) {
savedMatrix.set(matrix);
midPoint(mid, event);
mode = ZOOM;
Log.d(TAG, "mode=ZOOM");
}
click = false;
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
Log.d(TAG, "mode=NONE");
if(click)
onClick(event.getX(), event.getY(),true);
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG) {
temp_x = ((start.x) - ((event.getX()/metric.widthPixels)*800));
temp_y = ((start.y) - ((event.getY()/metric.heightPixels) * 480));
if(FloatMath.sqrt(temp_x * temp_x + temp_y * temp_y)< 10)
break;
matrix.set(savedMatrix);
// limit pan
matrix.getValues(matrixValues);
float currentY = matrixValues[Matrix.MTRANS_Y];
float currentX = matrixValues[Matrix.MTRANS_X];
float currentScale = matrixValues[Matrix.MSCALE_X];
float currentHeight = height * currentScale;
float currentWidth = width * currentScale;
float dx = (event.getX()/metric.widthPixels * 800) - start.x;
float dy = (event.getY()/metric.heightPixels * 480) - start.y;
float newX = currentX+dx;
float newY = currentY+dy;
RectF drawingRect = new RectF(newX, newY, newX+currentWidth, newY+currentHeight);
float diffUp = Math.min(viewRect.bottom-drawingRect.bottom, viewRect.top-drawingRect.top);
float diffDown = Math.max(viewRect.bottom-drawingRect.bottom, viewRect.top-drawingRect.top);
float diffLeft = Math.min(viewRect.left-drawingRect.left, viewRect.right-drawingRect.right);
float diffRight = Math.max(viewRect.left-drawingRect.left, viewRect.right-drawingRect.right);
if(diffUp > 0 ){
dy +=diffUp;
}
if(diffDown < 0){
dy +=diffDown;
}
if( diffLeft> 0){
dx += diffLeft;
}
if(diffRight < 0){
dx += diffRight;
}
matrix.postTranslate(dx, dy);
//selection.set(selection.x + dx, selection.y + dy);
click = false;
}
else if (mode == ZOOM) {
float newDist = spacing(event);
Log.d(TAG, "newDist=" + newDist);
if (newDist > 10f) {
matrix.set(savedMatrix);
float scale = newDist / oldDist;
matrix.getValues(matrixValues);
float currentScale = matrixValues[Matrix.MSCALE_X];
// limit zoom
if (scale * currentScale > maxZoom) {
scale = maxZoom / currentScale;
} else if (scale * currentScale < minZoom) {
scale = minZoom / currentScale;
}
matrix.postScale(scale, scale, mid.x, mid.y);
}
}
break;
}
float mv[] = new float[9];
matrix.getValues(mv);
Log.d("PV", "Click x " + mv[Matrix.MTRANS_X] + " y " + mv[Matrix.MTRANS_Y] + " cx " + event.getX() + " cy " + event.getY());
view.setImageMatrix(matrix);
view.invalidate();
return true; // indicate event was handled
}
public void onClick(float x, float y,boolean state){
Log.d("TAG","x="+x+" y "+y);
float mv[] = new float[9];
matrix.getValues(mv);
if(btsize != null)
btsize.recycle();
btsize = BitmapFactory.decodeResource(getResources(), R.drawable.map);
if(btSel != null)
btSel.recycle();
btSel = BitmapFactory.decodeResource(getResources(), R.drawable.mfigure);
Canvas canvas;
try{
canvas = new Canvas(btsize);
}
catch(Exception e){
btsize = BitmapFactory.decodeResource(getResources(), R.drawable.map).copy(Config.ARGB_8888,true);
canvas = new Canvas(btsize);
}
x -= mv[Matrix.MTRANS_X];
y -= mv[Matrix.MTRANS_Y];
float wdt = btsize.getWidth() * mv[Matrix.MSCALE_X];
float ht = btsize.getHeight() * mv[Matrix.MSCALE_Y];
float tw = x/wdt;
float th = y/ht;
selPoint.set(tw, th);
if(state)
canvas.drawBitmap(btSel, (tw * btsize.getWidth()) - (btSel.getWidth()/2), (th * btsize.getHeight()) - (btSel.getHeight()/2), null);
else
canvas.drawBitmap(btSel, (x * btsize.getWidth()) - (btSel.getWidth()/2), (y * btsize.getHeight()) - (btSel.getHeight()/2), null);
setImageBitmap(btsize);
}
/** Determine the space between the first two fingers */
private float spacing(MotionEvent event) {
float x = ((event.getX(0)/metric.widthPixels)*800) - ((event.getX(1)/metric.widthPixels)*800);
float y = ((event.getY(0)/metric.heightPixels) * 480) - ((event.getY(1)/metric.heightPixels) * 480);
return FloatMath.sqrt(x * x + y * y);
}
/** Calculate the mid point of the first two fingers */
private void midPoint(PointF point, MotionEvent event) {
float x = ((event.getX(0)/metric.widthPixels) * 800) + ((event.getX(1)/metric.widthPixels)*800);
float y = ((event.getY(0)/metric.heightPixels) * 480) + ((event.getY(1)/metric.heightPixels) * 480);
point.set(x / 2, y / 2);
}
private static final String TAG = "Touch";
// These matrices will be used to move and zoom image
Matrix matrix = new Matrix();
Matrix savedMatrix = new Matrix();
// We can be in one of these 3 states
static final int NONE = 0;
static final int DRAG = 1;
static final int ZOOM = 2;
int mode = NONE;
// Remember some things for zooming
PointF start = new PointF();
PointF mid = new PointF();
float oldDist = 1f;
// Limit zoomable/pannable image
private ImageView view;
private float[] matrixValues = new float[9];
private float maxZoom;
private float minZoom;
private float height;
private float width;
private RectF viewRect;
private float temp_x,temp_y;
private boolean click = false;
public PointF selPoint = new PointF();
Bitmap bMap;
private float d_dpi;
Paint paint = new Paint();
Canvas canvas = new Canvas();
private DisplayMetrics metric;
Bitmap bt = null;
Bitmap btsize = null;
Bitmap btSel = null;
}
Try using FrameLayout
and have a look at this official document: Zooming a View.