Imageview Drag Limitation In Android
Solution 1:
Add the following parameters to the Touch
class:
privatefloat dx; // postTranslate X distanceprivatefloat dy; // postTranslate Y distanceprivatefloat[] matrixValues = newfloat[9];
float matrixX = 0; // X coordinate of matrix inside the ImageViewfloat matrixY = 0; // Y coordinate of matrix inside the ImageViewfloat width = 0; // width of drawablefloat height = 0; // height of drawable
Modify your code after case MotionEvent.ACTION_MOVE:
if (mode == DRAG) {
matrix.set(savedMatrix);
matrix.getValues(matrixValues);
matrixX = matrixValues[2];
matrixY = matrixValues[5];
width = matrixValues[0] * (((ImageView) view).getDrawable()
.getIntrinsicWidth());
height = matrixValues[4] * (((ImageView) view).getDrawable()
.getIntrinsicHeight());
dx = event.getX() - start.x;
dy = event.getY() - start.y;
//if image will go outside left boundif (matrixX + dx < 0){
dx = -matrixX;
}
//if image will go outside right boundif(matrixX + dx + width > view.getWidth()){
dx = view.getWidth() - matrixX - width;
}
//if image will go oustside top boundif (matrixY + dy < 0){
dy = -matrixY;
}
//if image will go outside bottom boundif(matrixY + dy + height > view.getHeight()){
dy = view.getHeight() - matrixY - height;
}
matrix.postTranslate(dx, dy);
}
Solution 2:
Android documentation says:
It is possible to retrieve the location of a view by invoking the methods getLeft() and getTop(). The former returns the left, or X, coordinate of the rectangle representing the view. The latter returns the top, or Y, coordinate of the rectangle representing the view. These methods both return the location of the view relative to its parent. In addition, several convenience methods are offered to avoid unnecessary computations, namely getRight() and getBottom(). These methods return the coordinates of the right and bottom edges of the rectangle representing the view. For instance, calling getRight() is similar to the following computation: getLeft() + getWidth().
So you can get your image coordinates before moving it,and you can compute measure of movement in your OnTouchListener class.Now if (X coordinate of your image plus horizontal movement that you computed,be greater than device width
or Y coordinate of your image plus vertical movement that you computed,be greater than device height
) your image not move.
Solution 3:
I used the answer from Benito Bertoli and modified the ACTION_MOVE code changing minor and major sign to make image zoom and drag for image zoomed
here´s the code
privatestatic final float MIN_ZOOM = 1f;
privatestatic final float MAX_ZOOM = 2.5f;
public boolean onTouch(View v, MotionEvent event) {
ImageView view = (ImageView) v;
view.setScaleType(ImageView.ScaleType.MATRIX);
// Handle touch events here...switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: //first finger down only
savedMatrix.set(matrix);
start.set(event.getX(), event.getY());
Log.d(TAG, "mode=DRAG" );
mode = DRAG;
break;
case MotionEvent.ACTION_UP: //first finger liftedcase MotionEvent.ACTION_POINTER_UP: //second finger lifted
mode = NONE;
Log.d(TAG, "mode=NONE" );
break;
case MotionEvent.ACTION_POINTER_DOWN: //second finger 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" );
}
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG) {
//matrix.set(savedMatrix);//matrix.postTranslate(event.getX() - start.x, event.getY() - start.y);
matrix.set(savedMatrix);
matrix.getValues(matrixValues);
matrixX = matrixValues[2];
matrixY = matrixValues[5];
width = matrixValues[0] * (view.getDrawable().getIntrinsicWidth());
height = matrixValues[4] * (view.getDrawable().getIntrinsicHeight());
dx = event.getX() - start.x;
dy = event.getY() - start.y;
//if image will go outside left boundif (matrixX + dx > 0){
Log.e("dx","lef bound " + dx);
dx = -matrixX;
}
//if image will go outside right boundif(matrixX + dx + width < view.getWidth()){
dx = view.getWidth() - matrixX - width;
}
//if image will go oustside top boundif (matrixY + dy > 0){
dy = -matrixY;
}
//if image will go outside bottom boundif(matrixY + dy + height < view.getHeight()){
dy = view.getHeight() - matrixY - height;
}
matrix.postTranslate(dx, dy);
}
elseif (mode == ZOOM) {
Float newDist = spacing(event);
Log.d(TAG, "newDist=" + newDist);
if (newDist > 10f) {
matrix.set(savedMatrix);
float scale = newDist / oldDist;
float[] values = newfloat[9];
matrix.getValues(values);
float currentScale = values[Matrix.MSCALE_X];
if(scale * currentScale > MAX_ZOOM)
scale = MAX_ZOOM / currentScale;
elseif (scale * currentScale < MIN_ZOOM)
scale = MIN_ZOOM / currentScale;
matrix.postScale(scale, scale, mid.x, mid.y);
}
break;
}
} //perform the transformation.
view.setImageMatrix(matrix);
returntrue; // indicate event was handled
}
privatefloatspacing(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);
}
privatevoidmidPoint(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);
}
return drawable;
}
Solution 4:
We need to create two Rect objects, one is for our view and another for our image according to the view coordinates.
float[] values=newfloat[9]; matrix.getValues(values); float globalX =values[Matrix.MTRANS_X]; float globalY =values[Matrix.MTRANS_Y]; float scaleX =values[Matrix.MSCALE_X]; float scaleY =values[Matrix.MSCALE_Y]; Rect viewRect =new Rect(0, 0, viewWidth, viewHeight); Rect imageRect =new Rect((int) globalX, (int) globalY, Math.round(bitmapWidth * scaleX + globalX), Math.round(bitmapHeight * scaleY + globalY));
If we want our image be always inside our view, then we check this:
if (!viewRect.contains(imageRect)) { matrix.set(lastSetMatrix); //return to last saved parameters }
Sometimes we need our image always be bigger than our view to position a part of the image inside the view, then we can check this:
if (!imageRect.contains(viewRect)) { matrix.set(lastSetMatrix); }
Solution 5:
I have done this code. when I zoom hen it should not go out of boundry. its working fine.But when it touches cordinate of x=0 and y=0 it do not minimize.
int FLAG=0;
elseif (mode == ZOOM) {
float newDistance = spacing(event);
Log.i("new distance ", newDistance+"");
matrix.getValues(matrixValues);
matrixX = matrixValues[2];
matrixY = matrixValues[5];
width = matrixValues[0]
* (((ImageView) view).getDrawable().getIntrinsicWidth());
height = matrixValues[4]
* (((ImageView) view).getDrawable()
.getIntrinsicHeight());
dx = event.getX() - start.x;
dy = event.getY() - start.y;
// if image will go outside left boundif (matrixX + dx < 0) {
FLAG=1;
}
if (matrixX + dx + width > view.getWidth()) {
FLAG=1;
//dx = view.getWidth() - matrixX - width;
}
// if image will go oustside top boundif (matrixY + dy < 0) {
FLAG=1;
//dy = -matrixY;
}
// if image will go outside bottom boundif (matrixY + dy + height > view.getHeight()) {
FLAG=1;
//dy = view.getHeight() - matrixY - height;
}
if (matrixX + dx ==0 || matrixY + dy==0){
FLAG=0;
}
if (newDistance > 10f && FLAG==0) {
matrix.set(savedMatrix);
float scale = newDistance / oldDistance;
float[] values = newfloat[9];
matrix.getValues(values);
float currentScale = values[Matrix.MSCALE_X];
if (scale * currentScale > MAX_ZOOM)
scale = MAX_ZOOM / currentScale;
elseif (scale * currentScale < MIN_ZOOM)
scale = MIN_ZOOM / currentScale;
matrix.postScale(scale, scale, mid.x, mid.y);
}
}
break;
Post a Comment for "Imageview Drag Limitation In Android"