Android Zoomview center - android

I tried to create a zoom view with an image that is always scaled about its center. However, if I change the initial position of the image and pinch the image moves to the lower right corner of the window. As a reference I used the pinch zoom view of the Android Developer and changed some parameters. You have any ideas to fix that?
package android.oli.com.fitnessapp;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
public class ZoomView extends View{
private Drawable mIcon;
private float mPosX;
private float mPosY;
private float mLastTouchX;
private float mLastTouchY;
private ScaleGestureDetector mScaleDetector;
private float mScaleFactor = 1.f;
private static final int INVALID_POINTER_ID = -1;
// The ‘active pointer’ is the one currently moving our object.
private int mActivePointerId = INVALID_POINTER_ID;
Context context;
public ZoomView(Context context) {
super(context);
mIcon = context.getResources().getDrawable(R.drawable.image_1);
this.context = context;
init();
}
public ZoomView(Context context, AttributeSet attrs) {
super(context, attrs);
mIcon = context.getResources().getDrawable(R.drawable.image_1);
this.context = context;
init();
}
public ZoomView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mIcon = context.getResources().getDrawable(R.drawable.image_1);
this.context = context;
init();
}
public void init(){
mIcon.setBounds(0, 0, mIcon.getIntrinsicWidth(), mIcon.getIntrinsicHeight());
mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
}
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
canvas.translate(mPosX - ((mIcon.getIntrinsicWidth()) * mScaleFactor) / 2, mPosY - ((mIcon.getIntrinsicWidth()) * mScaleFactor) / 2);
canvas.scale(mScaleFactor, mScaleFactor);
mIcon.draw(canvas);
//rectMid.set(0, 0, canvas.getWidth(), canvas.getHeight()/2);
//canvas.drawRect(rectMid, blue);
canvas.restore();
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
// Let the ScaleGestureDetector inspect all events.
mScaleDetector.onTouchEvent(ev);
final int action = ev.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
final float x = ev.getX();
final float y = ev.getY();
mLastTouchX = x;
mLastTouchY = y;
mActivePointerId = ev.getPointerId(0);
break;
}
case MotionEvent.ACTION_MOVE: {
final int pointerIndex = ev.findPointerIndex(mActivePointerId);
final float x = ev.getX(pointerIndex);
final float y = ev.getY(pointerIndex);
// Only move if the ScaleGestureDetector isn't processing a gesture.
if (!mScaleDetector.isInProgress()) {
final float dx = x - mLastTouchX;
final float dy = y - mLastTouchY;
mPosX += dx;
mPosY += dy;
invalidate();
}
mLastTouchX = x;
mLastTouchY = y;
break;
}
case MotionEvent.ACTION_UP: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_CANCEL: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_POINTER_UP: {
final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK)
>> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
final int pointerId = ev.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;
mLastTouchX = ev.getX(newPointerIndex);
mLastTouchY = ev.getY(newPointerIndex);
mActivePointerId = ev.getPointerId(newPointerIndex);
}
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;
}
}
}
XML:
<android.oli.com.fitnessapp.ZoomView
android:layout_width="match_parent"
android:layout_height="match_parent" />

Ok i got it :D
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
public class ZoomView extends View{
private Drawable mIcon;
private float mPosX;
private float mPosY;
private float mLastTouchX;
private float mLastTouchY;
private ScaleGestureDetector mScaleDetector;
private float mScaleFactor = 1.f;
private static final int INVALID_POINTER_ID = -1;
// The ‘active pointer’ is the one currently moving our object.
private int mActivePointerId = INVALID_POINTER_ID;
Context context;
int height, width;
public ZoomView(Context context) {
super(context);
mIcon = context.getResources().getDrawable(R.drawable.image_1);
this.context = context;
init();
}
public ZoomView(Context context, AttributeSet attrs) {
super(context, attrs);
mIcon = context.getResources().getDrawable(R.drawable.image_1);
this.context = context;
init();
}
public ZoomView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mIcon = context.getResources().getDrawable(R.drawable.image_1);
this.context = context;
init();
}
public void init(){
DisplayMetrics displaymetrics = new DisplayMetrics();
((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
height = displaymetrics.heightPixels;
width = displaymetrics.widthPixels;
mIcon.setBounds(0, 0, 0 + mIcon.getIntrinsicWidth(), 0 + mIcon.getIntrinsicHeight());
mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
}
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
canvas.translate(width/2 + mPosX - (mIcon.getIntrinsicWidth() * mScaleFactor) / 2, height/2 + mPosY - (mIcon.getIntrinsicWidth() * mScaleFactor) / 2);
canvas.scale(mScaleFactor, mScaleFactor);
mIcon.draw(canvas);
//rectMid.set(0, 0, canvas.getWidth(), canvas.getHeight()/2);
//canvas.drawRect(rectMid, blue);
canvas.restore();
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
// Let the ScaleGestureDetector inspect all events.
mScaleDetector.onTouchEvent(ev);
final int action = ev.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
final float x = ev.getX();
final float y = ev.getY();
mLastTouchX = x;
mLastTouchY = y;
mActivePointerId = ev.getPointerId(0);
break;
}
case MotionEvent.ACTION_MOVE: {
final int pointerIndex = ev.findPointerIndex(mActivePointerId);
final float x = ev.getX(pointerIndex);
final float y = ev.getY(pointerIndex);
// Only move if the ScaleGestureDetector isn't processing a gesture.
if (!mScaleDetector.isInProgress()) {
final float dx = x - mLastTouchX;
final float dy = y - mLastTouchY;
mPosX += dx;
mPosY += dy;
invalidate();
}
mLastTouchX = x;
mLastTouchY = y;
break;
}
case MotionEvent.ACTION_UP: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_CANCEL: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_POINTER_UP: {
final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK)
>> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
final int pointerId = ev.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;
mLastTouchX = ev.getX(newPointerIndex);
mLastTouchY = ev.getY(newPointerIndex);
mActivePointerId = ev.getPointerId(newPointerIndex);
}
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;
}
}
}

Related

Unable to Multi touch - zoom relative layout from pinch in android

package com.example.demo;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import android.widget.RelativeLayout;
public class MyLayout extends RelativeLayout {
private static final int INVALID_POINTER_ID = -1;
private Drawable mIcon;
private float mPosX;
private float mPosY;
MyLayout temp;
private float mLastTouchX;
private float mLastTouchY;
private int mActivePointerId = INVALID_POINTER_ID;
private ScaleGestureDetector mScaleDetector;
private float mScaleFactor = 1.f;
public MyLayout(Context context) {
this(context, null, 0);
temp = this;
}
public MyLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
temp = this;
}
public MyLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mIcon = context.getResources()
.getDrawable(R.drawable.ic_launcher);
mIcon.setBounds(0, 0, mIcon.getIntrinsicWidth(),
mIcon.getIntrinsicHeight());
temp = this;
mScaleDetector = new ScaleGestureDetector(context,
new ScaleListener());
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
// Let the ScaleGestureDetector inspect all events.
mScaleDetector.onTouchEvent(ev);
final int action = ev.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
final float x = ev.getX();
final float y = ev.getY();
mLastTouchX = x;
mLastTouchY = y;
mActivePointerId = ev.getPointerId(0);
break;
}
case MotionEvent.ACTION_MOVE: {
final int pointerIndex = ev
.findPointerIndex(mActivePointerId);
final float x = ev.getX(pointerIndex);
final float y = ev.getY(pointerIndex);
// Only move if the ScaleGestureDetector isn't processing a
// gesture.
if (!mScaleDetector.isInProgress()) {
final float dx = x - mLastTouchX;
final float dy = y - mLastTouchY;
mPosX += dx;
mPosY += dy;
invalidate();
}
mLastTouchX = x;
mLastTouchY = y;
break;
}
case MotionEvent.ACTION_UP: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_CANCEL: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_POINTER_UP: {
final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
final int pointerId = ev.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;
mLastTouchX = ev.getX(newPointerIndex);
mLastTouchY = ev.getY(newPointerIndex);
mActivePointerId = ev.getPointerId(newPointerIndex);
}
break;
}
}
return true;
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int count = getChildCount();
Log.d("onLayout", "" + count);
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
if (child.getVisibility() != GONE) {
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) child
.getLayoutParams();
child.layout((int) (params.leftMargin * mScaleFactor),
(int) (params.topMargin * mScaleFactor),
(int) ((params.leftMargin + child
.getMeasuredWidth()) * mScaleFactor),
(int) ((params.topMargin + child
.getMeasuredHeight()) * mScaleFactor));
child.setLayoutParams(params);
}
}
}
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save(Canvas.MATRIX_SAVE_FLAG);
// canvas.translate(mLastTouchX, mLastTouchY);
canvas.translate(mPosX, mPosY);
canvas.scale(mScaleFactor, mScaleFactor);
System.out.println("onDraw");
int count = getChildCount();
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
if (child.getVisibility() != GONE) {
child.draw(canvas);
Log.d("onDraw", "" + mScaleFactor);
}
}
canvas.restore();
}
#Override
protected void dispatchDraw(Canvas canvas) {
canvas.save(Canvas.MATRIX_SAVE_FLAG);
System.out.println("dispatchDraw");
System.out.println("x :: " + mPosX + " :: X2 :: " + mLastTouchX);
System.out.println("y :: " + mPosY + " :: Y2 :: " + mLastTouchY);
System.out.println("Scale factor :: " + mScaleFactor);
canvas.translate(
mPosX
- ((mLastTouchX * mScaleFactor) - mLastTouchX),
mPosY
- ((mLastTouchY * mScaleFactor) - mLastTouchY));
canvas.scale(mScaleFactor, mScaleFactor);
super.dispatchDraw(canvas);
canvas.restore();
}
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(1.0f, Math.min(mScaleFactor, 5.0f));
// Log.d("onScale", ""+mScaleFactor);
temp.invalidate();
invalidate();
return true;
}
}
}
Above code is for custom relative layout for pinch zoom and move with finger on screen.
But, above code is working properly. but problem is that I unable to implement zoom from where I pinch on screen.
Please help me for this.
I took a references from below link.
Zoom and Pinch RelativeLayout

Android Pinch to Zoom ImageView

I have a single Image ImageView Layout .
import android.app.Activity;
import android.os.Bundle;
public class americanfootball extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.americanfootball);
}
}
How to enable simple pinch to zoom on the image ?
You have to use a custom ImageView to do that. use something like this:
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
public class PinchImageView extends View {
private static final int INVALID_POINTER_ID = -1;
private Drawable mImage;
private float mPosX;
private float mPosY;
private float mLastTouchX;
private float mLastTouchY;
private int mActivePointerId = INVALID_POINTER_ID;
private ScaleGestureDetector mScaleDetector;
private float mScaleFactor = 1.f;
public PinchImageView(Context context) {
this(context, null, 0);
mImage=act.getResources().getDrawable(context.getResources().getIdentifier("imag­ename", "drawable", "packagename"));
mImage.setBounds(0, 0, mImage.getIntrinsicWidth(), mImage.getIntrinsicHeight());
}
public PinchImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public PinchImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
// Let the ScaleGestureDetector inspect all events.
mScaleDetector.onTouchEvent(ev);
final int action = ev.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
final float x = ev.getX();
final float y = ev.getY();
mLastTouchX = x;
mLastTouchY = y;
mActivePointerId = ev.getPointerId(0);
break;
}
case MotionEvent.ACTION_MOVE: {
final int pointerIndex = ev.findPointerIndex(mActivePointerId);
final float x = ev.getX(pointerIndex);
final float y = ev.getY(pointerIndex);
// Only move if the ScaleGestureDetector isn't processing a gesture.
if (!mScaleDetector.isInProgress()) {
final float dx = x - mLastTouchX;
final float dy = y - mLastTouchY;
mPosX += dx;
mPosY += dy;
invalidate();
}
mLastTouchX = x;
mLastTouchY = y;
break;
}
case MotionEvent.ACTION_UP: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_CANCEL: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_POINTER_UP: {
final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK)
>> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
final int pointerId = ev.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;
mLastTouchX = ev.getX(newPointerIndex);
mLastTouchY = ev.getY(newPointerIndex);
mActivePointerId = ev.getPointerId(newPointerIndex);
}
break;
}
}
return true;
}
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
Log.d("DEBUG", "X: "+mPosX+" Y: "+mPosY);
canvas.translate(mPosX, mPosY);
canvas.scale(mScaleFactor, mScaleFactor);
mImage.draw(canvas);
canvas.restore();
}
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, 10.0f));
invalidate();
return true;
}
}
}
Instead of creating a custom ImageView try this open-source library: https://github.com/martinwithaar/PinchToZoom
It doesn't extend the ImageView class so you could potentially use other ImageView implementations as well. Besides that it has some really sleek animations IMHO.
You can see the link below:
https://androidcookbook.com/Recipe.seam?recipeId=2273
Note:
This is the greatest pinch to Zoom (and move) example I had ever found!
add android:scaleType="matrix" to your ImageView in XML file.
ex:
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" app:srcCompat="#drawable/menu2" android:id="#+id/imageView7"android:scaleType="matrix"
/>
copy the code and paste in your activity
remember to change the code below to your own image.
"ImageView view = (ImageView) findViewById(R.id.imageView);"

Drag multiple images in a canvas by touching in android

How can we drag more than one image in a canvas? I have a code to drag single image. I tried for moving multiple image. But it didn't work. Is there any way to do this one? This is the code for moving one image.. Thanks in advance
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
public class MyImageView extends View {
private static final int INVALID_POINTER_ID = -1;
private Drawable mImage;
private float mPosX;
private float mPosY;
private float mLastTouchX;
private float mLastTouchY;
private int mActivePointerId = INVALID_POINTER_ID;
private ScaleGestureDetector mScaleDetector;
private float mScaleFactor = 1.f;
public MyImageView(Context context) {
this(context, null, 0);
mImage = getResources().getDrawable(R.drawable.baby1);
mImage.setBounds(0, 0, mImage.getIntrinsicWidth(), mImage.getIntrinsicHeight());
}
public MyImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
// Let the ScaleGestureDetector inspect all events.
mScaleDetector.onTouchEvent(ev);
final int action = ev.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
final float x = ev.getX();
final float y = ev.getY();
mLastTouchX = x;
mLastTouchY = y;
mActivePointerId = ev.getPointerId(0);
break;
}
case MotionEvent.ACTION_MOVE: {
final int pointerIndex = ev.findPointerIndex(mActivePointerId);
final float x = ev.getX(pointerIndex);
final float y = ev.getY(pointerIndex);
// Only move if the ScaleGestureDetector isn't processing a gesture.
if (!mScaleDetector.isInProgress()) {
final float dx = x - mLastTouchX;
final float dy = y - mLastTouchY;
mPosX += dx;
mPosY += dy;
invalidate();
}
mLastTouchX = x;
mLastTouchY = y;
break;
}
case MotionEvent.ACTION_UP: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_CANCEL: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_POINTER_UP: {
final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK)
>> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
final int pointerId = ev.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;
mLastTouchX = ev.getX(newPointerIndex);
mLastTouchY = ev.getY(newPointerIndex);
mActivePointerId = ev.getPointerId(newPointerIndex);
}
break;
}
}
return true;
}
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
Log.d("DEBUG", "X: "+mPosX+" Y: "+mPosY);
canvas.translate(mPosX, mPosY);
canvas.scale(mScaleFactor, mScaleFactor);
mImage.draw(canvas);
canvas.restore();
}
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, 10.0f));
invalidate();
return true;
}
}
}
I'm in search of the same thing ,so I guess is one of this 2 answers will work:
So chatgtp to find a answer just feed it your code and your problem and try it till it's what you need
or maybe store the X Y coordinates for the multiple views you want to drag and override the onTouch and check if the xy coordinates are inside any of the imageviews (this code can be found on geeksforgeeks website in java,cpp etc),if not then don't do anything else update the coordinates of the view to 'drag' the view to the new coordinates using the code from the single choice view.the only extra step is to check using xy coordinates of the imageviews if the touch event is 'inside' the view
or check Android drag two images on canvas where it gives a library that handles all of it
If you don't mind I just post my code snippet, maybe it will help you to figure out the problem.
To use this snippet just add in your layout xml file:
<com.m039.study.widgets.MultiTouch
android:layout_width = "match_parent"
android:layout_height = "match_parent"
/>
This snippet just draw circle on each finger on the view:
package com.m039.study.widgets;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.MotionEvent;
import android.view.GestureDetector;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Color;
import java.util.Stack;
public class MultiTouch extends View {
private static final String TAG = "m039";
public MultiTouch(Context c) {
super(c);
}
public MultiTouch(Context context, AttributeSet attrs) {
super(context, attrs);
}
static class Point {
public float x;
public float y;
public int pid = -1;
public boolean isOk = false;
}
Paint mPaintCircle = new Paint();
Paint mPaintText = new Paint();
Stack<Point> mPoints = new Stack<Point>();
{
mPaintCircle.setColor(Color.GREEN);
mPaintText.setColor(Color.RED);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for (Point point : mPoints) {
if (point.isOk) {
canvas.drawCircle(point.x, point.y, 50, mPaintCircle);
canvas.drawText(Integer.toString(point.pid), point.x, point.y + 50, mPaintText);
}
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getActionMasked();
int pid = (event.getAction() & event.ACTION_POINTER_ID_MASK) >> event.ACTION_POINTER_ID_SHIFT;
int index = (event.getAction() & event.ACTION_POINTER_INDEX_MASK) >> event.ACTION_POINTER_INDEX_SHIFT;
switch (action) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
Point point = new Point();
point.isOk = true;
point.pid = pid;
point.x = event.getX(index);
point.y = event.getY(index);
mPoints.push(point);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
for (Point p: mPoints) {
int pindex = event.findPointerIndex(p.pid);
if (pindex != -1) {
p.x = event.getX(pindex);
p.y = event.getY(pindex);
}
}
invalidate();
break;
case MotionEvent.ACTION_POINTER_UP:
if (mPoints.size() >= 1) {
mPoints.pop();
}
invalidate();
break;
case MotionEvent.ACTION_UP:
default:
mPoints.clear();
invalidate();
break;
}
return true;
}
}
P.S. Please, tell me if it is helpful or not.

how to show zoomed part of image and drag the image to left, right ,top ,bottom on touch of image

I need to show zoomed part of an image and the image should move to left, right, top, bottom when image is dragged(touched) accrodingly.
I am using imageview for this.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:id="#+id/imageView2">
</ImageView>
</LinearLayout>
Please help. how can i do this?
Thanks
Jyoti
try this..
1. Draw your image on canvas..
2. scale the canvas for zoom in - zoom put.
EDIT: try this..
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
public class MyImageView extends View {
private static final int INVALID_POINTER_ID = -1;
private Drawable mImage;
private float mPosX;
private float mPosY;
private float mLastTouchX;
private float mLastTouchY;
private int mActivePointerId = INVALID_POINTER_ID;
private ScaleGestureDetector mScaleDetector;
private float mScaleFactor = 1.f;
public MyImageView(Context context) {
this(context, null, 0);
mImage = getResources().getDrawable(R.drawable.imagename);
mImage.setBounds(0, 0, mImage.getIntrinsicWidth(), mImage.getIntrinsicHeight());
}
public MyImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
// Let the ScaleGestureDetector inspect all events.
mScaleDetector.onTouchEvent(ev);
final int action = ev.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
final float x = ev.getX();
final float y = ev.getY();
mLastTouchX = x;
mLastTouchY = y;
mActivePointerId = ev.getPointerId(0);
break;
}
case MotionEvent.ACTION_MOVE: {
final int pointerIndex = ev.findPointerIndex(mActivePointerId);
final float x = ev.getX(pointerIndex);
final float y = ev.getY(pointerIndex);
// Only move if the ScaleGestureDetector isn't processing a gesture.
if (!mScaleDetector.isInProgress()) {
final float dx = x - mLastTouchX;
final float dy = y - mLastTouchY;
mPosX += dx;
mPosY += dy;
invalidate();
}
mLastTouchX = x;
mLastTouchY = y;
break;
}
case MotionEvent.ACTION_UP: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_CANCEL: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_POINTER_UP: {
final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK)
>> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
final int pointerId = ev.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;
mLastTouchX = ev.getX(newPointerIndex);
mLastTouchY = ev.getY(newPointerIndex);
mActivePointerId = ev.getPointerId(newPointerIndex);
}
break;
}
}
return true;
}
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
Log.d("DEBUG", "X: "+mPosX+" Y: "+mPosY);
canvas.translate(mPosX, mPosY);
canvas.scale(mScaleFactor, mScaleFactor);
mImage.draw(canvas);
canvas.restore();
}
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, 10.0f));
invalidate();
return true;
}
}
}
to call this in your activity,setContentView(new MyImageView(this));
EDIT: zooming and dragging images using matrix in android And for zoom /resize the image look at my answer on How to load an image and resize it immediately to use later.
i think you can use a customized view, and draw bitmap(left, top, right, bottom) on the canvas.

Adding custom View and ImageView to a single Layout

I want to add some images to the View of an app. The app uses a custom view for its normal working but I want some images along with the custom View. I have tried adding a Layout as the contenView in which I added the ImageView and the custom View, but its not comming to the screen.
Can any one give me some idea on this...
thanks in advance.
Code:
MyView view;
LinearLayout ly;
LinearLayout.LayoutParams lp;
LinearLayout.LayoutParams ImageViewlp;
lp=new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
ImageViewlp=new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
ly=new LinearLayout(this);
sketchBoard.setBackgroundColor(0);
ImageView img=new ImageView(this);
img.setBackgroundColor(R.drawable.img);
ly.addView(img,ImageViewlp);
view=new MyView(this);
ly.addView(view);
this.addContentView(ly, lp);
Edit:
img.setBackgroundResource(R.drawable.img);
I got it solved by changing img.setBackgroundColor(R.drawable.img); with the above one
You are doing this, but this result in drawing a BG color of whatever value R.Drawable.img is
img.setBackgroundColor(R.drawable.img);
should be
img.setBackgroundResource(R.drawable.img);
or better yet actually use the imageview's drawable resource and do
img.setImageResource(R.drawable.img);
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
public class MyImageView extends View {
private static final int INVALID_POINTER_ID = -1;
private Drawable mImage;
private float mPosX;
private float mPosY;
private float mLastTouchX;
private float mLastTouchY;
private int mActivePointerId = INVALID_POINTER_ID;
private ScaleGestureDetector mScaleDetector;
private float mScaleFactor = 1.f;
public MyImageView(Context context,String uri) {
this(context, null, 0);
mImage = Drawable.createFromPath(uri);
mImage.setBounds(0, 0, mImage.getIntrinsicWidth(), mImage.getIntrinsicHeight());
}
public MyImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
// Let the ScaleGestureDetector inspect all events.
mScaleDetector.onTouchEvent(ev);
final int action = ev.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
final float x = ev.getX();
final float y = ev.getY();
mLastTouchX = x;
mLastTouchY = y;
mActivePointerId = ev.getPointerId(0);
break;
}
case MotionEvent.ACTION_MOVE: {
final int pointerIndex = ev.findPointerIndex(mActivePointerId);
final float x = ev.getX(pointerIndex);
final float y = ev.getY(pointerIndex);
// Only move if the ScaleGestureDetector isn't processing a gesture.
if (!mScaleDetector.isInProgress()) {
final float dx = x - mLastTouchX;
final float dy = y - mLastTouchY;
mPosX += dx;
mPosY += dy;
invalidate();
}
mLastTouchX = x;
mLastTouchY = y;
break;
}
case MotionEvent.ACTION_UP: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_CANCEL: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_POINTER_UP: {
final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK)
>> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
final int pointerId = ev.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;
mLastTouchX = ev.getX(newPointerIndex);
mLastTouchY = ev.getY(newPointerIndex);
mActivePointerId = ev.getPointerId(newPointerIndex);
}
break;
}
}
return true;
}
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
Log.d("DEBUG", "X: "+mPosX+" Y: "+mPosY);
canvas.translate(mPosX, mPosY);
canvas.scale(mScaleFactor, mScaleFactor);
mImage.draw(canvas);
canvas.restore();
}
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, 10.0f));
invalidate();
return true;
}
}
}
call this through
import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
public class sampleLocalization extends Activity {
String uri="";
ImageView img;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
uri="pathname";
img.setImageResource(new touchview(context,uri));
}
}

Categories

Resources