I have a ListView with set of images. On clicking any of them, the clicked image will appear on a new activity and at the center of the activity in ImageView, also it is Zoomable. The Problem is when i zoom the image it gains Zoom but also moves like drag and drop. I should eliminate that movement of the image and should only be zoomable from the center of the activity.
ZoomInZoomOutActivity.java
public class ZoomInZoomOutActivity extends Activity implements OnTouchListener
{
private static final String TAG = "Touch";
#SuppressWarnings("unused")
private static final float MIN_ZOOM = 1f,MAX_ZOOM = 1f;
Matrix matrix = new Matrix();
Matrix savedMatrix = new Matrix();
static final int NONE = 0;
static final int DRAG = 1;
static final int ZOOM = 2;
int mode = NONE;
PointF start = new PointF();
PointF mid = new PointF();
float oldDist = 1f;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.imagedisp);
Bundle extras = getIntent().getExtras();
long id =extras.getLong("ID");
String s=String.valueOf(id);
ImageView view;
view = (ImageView) findViewById(R.id.imageView1);
view.setOnTouchListener(this);
if (s.equals("0"))
{
view.setImageResource(R.drawable.img1);
}
else if (s.equals("1"))
{
view.setImageResource(R.drawable.img2);
}
else if (s.equals("2"))
{
view.setImageResource(R.drawable.img3);
}
else
{
view.setImageResource(R.drawable.img4);
}
}
public boolean onTouch(View v, MotionEvent event)
{
ImageView view = (ImageView) v;
view.setScaleType(ImageView.ScaleType.MATRIX);
float scale;
switch (event.getAction() & MotionEvent.ACTION_MASK)
{
/*case MotionEvent.ACTION_DOWN:
savedMatrix.set(matrix);
start.set(event.getX(), event.getY());
Log.d(TAG, "mode=DRAG");
mode = DRAG;
break; */
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
Log.d(TAG, "mode=NONE");
break;
case MotionEvent.ACTION_POINTER_DOWN:
oldDist = spacing(event);
Log.d(TAG, "oldDist=" + oldDist);
if (oldDist > 5f) {
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);
}
else if (mode == ZOOM)
{
float newDist = spacing(event);
Log.d(TAG, "newDist=" + newDist);
if (newDist > 5f)
{
matrix.set(savedMatrix);
scale = newDist / oldDist;
matrix.postScale(scale, scale, mid.x, mid.y);
}
}
break;
}
view.setImageMatrix(matrix);
return true;
}
private float spacing(MotionEvent event)
{
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return FloatMath.sqrt(x * x + y * y);
}
private void midPoint(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);
}
}
imagedisp.xml
<?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"
android:gravity="center">
<ImageView android:layout_width="fill_parent"
android:id="#+id/imageView1"
android:src="#drawable/img1"
android:layout_height="fill_parent"
android:scaleType="centerInside">
</ImageView>
</LinearLayout>
Try this code:
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import android.widget.ImageView;
/**
* Extends Android ImageView to include pinch zooming and panning.
*/
public class TouchImageView extends ImageView
{
Matrix matrix = 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 last = new PointF();
PointF start = new PointF();
float minScale = 1f;
float maxScale = 3f;
float[] m;
float redundantXSpace, redundantYSpace;
float width, height;
static final int CLICK = 3;
float saveScale = 1f;
float right, bottom, origWidth, origHeight, bmWidth, bmHeight;
ScaleGestureDetector mScaleDetector;
Context context;
public TouchImageView(Context context)
{
super(context);
sharedConstructing(context);
}
public TouchImageView(Context context, AttributeSet attrs)
{
super(context, attrs);
sharedConstructing(context);
}
private void sharedConstructing(Context context)
{
super.setClickable(true);
this.context = context;
mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
matrix.setTranslate(1f, 1f);
m = new float[9];
setImageMatrix(matrix);
setScaleType(ScaleType.MATRIX);
setOnTouchListener(new OnTouchListener()
{
#Override
public boolean onTouch(View v, MotionEvent event)
{
mScaleDetector.onTouchEvent(event);
matrix.getValues(m);
float x = m[Matrix.MTRANS_X];
float y = m[Matrix.MTRANS_Y];
PointF curr = new PointF(event.getX(), event.getY());
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
last.set(event.getX(), event.getY());
start.set(last);
mode = DRAG;
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG)
{
float deltaX = curr.x - last.x;
float deltaY = curr.y - last.y;
float scaleWidth = Math.round(origWidth * saveScale);
float scaleHeight = Math.round(origHeight * saveScale);
if (scaleWidth < width)
{
deltaX = 0;
if (y + deltaY > 0)
deltaY = -y;
else if (y + deltaY < -bottom)
deltaY = -(y + bottom);
}
else if (scaleHeight < height)
{
deltaY = 0;
if (x + deltaX > 0)
deltaX = -x;
else if (x + deltaX < -right)
deltaX = -(x + right);
}
else
{
if (x + deltaX > 0)
deltaX = -x;
else if (x + deltaX < -right)
deltaX = -(x + right);
if (y + deltaY > 0)
deltaY = -y;
else if (y + deltaY < -bottom)
deltaY = -(y + bottom);
}
matrix.postTranslate(deltaX, deltaY);
last.set(curr.x, curr.y);
}
break;
case MotionEvent.ACTION_UP:
mode = NONE;
int xDiff = (int) Math.abs(curr.x - start.x);
int yDiff = (int) Math.abs(curr.y - start.y);
if (xDiff < CLICK && yDiff < CLICK)
performClick();
break;
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
break;
}
setImageMatrix(matrix);
invalidate();
return true; // indicate event was handled
}
});
}
#Override
public void setImageBitmap(Bitmap bm)
{
super.setImageBitmap(bm);
if (bm != null)
{
bmWidth = bm.getWidth();
bmHeight = bm.getHeight();
}
}
public void setMaxZoom(float x)
{
maxScale = x;
}
private class ScaleListener extends
ScaleGestureDetector.SimpleOnScaleGestureListener
{
#Override
public boolean onScaleBegin(ScaleGestureDetector detector)
{
mode = ZOOM;
return true;
}
#Override
public boolean onScale(ScaleGestureDetector detector)
{
float mScaleFactor = (float) Math.min(
Math.max(.95f, detector.getScaleFactor()), 1.05);
float origScale = saveScale;
saveScale *= mScaleFactor;
if (saveScale > maxScale)
{
saveScale = maxScale;
mScaleFactor = maxScale / origScale;
}
else if (saveScale < minScale)
{
saveScale = minScale;
mScaleFactor = minScale / origScale;
}
right = width * saveScale - width - (2 * redundantXSpace * saveScale);
bottom = height * saveScale - height
- (2 * redundantYSpace * saveScale);
if (origWidth * saveScale <= width || origHeight * saveScale <= height)
{
matrix.postScale(mScaleFactor, mScaleFactor, width / 2, height / 2);
if (mScaleFactor < 1)
{
matrix.getValues(m);
float x = m[Matrix.MTRANS_X];
float y = m[Matrix.MTRANS_Y];
if (mScaleFactor < 1)
{
if (Math.round(origWidth * saveScale) < width)
{
if (y < -bottom)
matrix.postTranslate(0, -(y + bottom));
else if (y > 0)
matrix.postTranslate(0, -y);
}
else
{
if (x < -right)
matrix.postTranslate(-(x + right), 0);
else if (x > 0)
matrix.postTranslate(-x, 0);
}
}
}
}
else
{
matrix.postScale(mScaleFactor, mScaleFactor, detector.getFocusX(),
detector.getFocusY());
matrix.getValues(m);
float x = m[Matrix.MTRANS_X];
float y = m[Matrix.MTRANS_Y];
if (mScaleFactor < 1)
{
if (x < -right)
matrix.postTranslate(-(x + right), 0);
else if (x > 0)
matrix.postTranslate(-x, 0);
if (y < -bottom)
matrix.postTranslate(0, -(y + bottom));
else if (y > 0)
matrix.postTranslate(0, -y);
}
}
return true;
}
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = MeasureSpec.getSize(widthMeasureSpec);
height = MeasureSpec.getSize(heightMeasureSpec);
// Fit to screen.
float scale;
float scaleX = (float) width / (float) bmWidth;
float scaleY = (float) height / (float) bmHeight;
scale = Math.min(scaleX, scaleY);
matrix.setScale(scale, scale);
setImageMatrix(matrix);
saveScale = 1f;
// Center the image
redundantYSpace = (float) height - (scale * (float) bmHeight);
redundantXSpace = (float) width - (scale * (float) bmWidth);
redundantYSpace /= (float) 2;
redundantXSpace /= (float) 2;
matrix.postTranslate(redundantXSpace, redundantYSpace);
origWidth = width - 2 * redundantXSpace;
origHeight = height - 2 * redundantYSpace;
right = width * saveScale - width - (2 * redundantXSpace * saveScale);
bottom = height * saveScale - height - (2 * redundantYSpace * saveScale);
setImageMatrix(matrix);
}
}
Related
This is my code to rotate the wheel and sound cordinator according to rotation but I want to rotate the wheel according to fix color on fix point.
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.graphics.RectF;
import android.media.MediaPlayer;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import com.spin.wheel.manager.MyDBAdapter;
import com.spin.wheel.manager.Prefs;
import com.spin.wheel.ui.activity.HomeActivity;
import java.util.List;
import java.util.Random;
public class WheelView extends View {
public boolean lifted;
private Paint circlePaint;
private long currTime;
private String item;
private Paint item10Paint;
private Paint item11Paint;
private Paint item12Paint;
private Paint item13Paint;
private Paint item14Paint;
private Paint item15Paint;
private Paint item1Paint;
private Paint item2Paint;
private Paint item3Paint;
private Paint item4Paint;
private Paint item5Paint;
private Paint item6Paint;
private Paint item7Paint;
private Paint item8Paint;
private Paint item9Paint;
private float itemLength;
private List<String> itemNames;
private double lastTheta;
private String listName;
private Paint markerPaint;
private long oldTime;
private Paint pointerPaint;
private int px;
WheelView wheelView;
private int py;
private float radius;
private MediaPlayer resourcePlayer;
private Paint rimPaint;
private double rotationOffset;
private int selected;
private Paint textPaint;
private boolean textSet;
private long timeDiff;
private Paint titlePaint;
private String winner;
int padding;
int center;
Context mContext;
public WheelView(Context context) {
super(context);
mContext=context;
initWheelView();
}
public WheelView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext=context;
initWheelView();
}
public WheelView(Context context, AttributeSet ats, int defaultStyle) {
super(context, ats, defaultStyle);
mContext=context;
initWheelView();
}
protected void initWheelView() {
setFocusable(true);
Resources r = getResources();
this.circlePaint = new Paint(1);
this.circlePaint.setColor(r.getColor(R.color.wheel_color));
this.circlePaint.setStrokeWidth(5.0f);
this.circlePaint.setStyle(Style.STROKE);
this.rimPaint = new Paint(1);
this.rimPaint.setColor(r.getColor(R.color.text_color));
this.rimPaint.setStrokeWidth(1.0f);
this.rimPaint.setStyle(Style.STROKE);
this.textPaint = new Paint(1);
this.textPaint.setColor(r.getColor(R.color.text_color));
this.titlePaint = new Paint(1);
this.titlePaint.setColor(r.getColor(R.color.text_color));
this.pointerPaint = new Paint(1);
this.pointerPaint.setColor(r.getColor(R.color.pointer_color));
this.markerPaint = new Paint(1);
this.markerPaint.setStrokeWidth(2.0f);
this.markerPaint.setColor(r.getColor(R.color.marker_color));
this.item1Paint = new Paint(1);
this.item1Paint.setColor(r.getColor(R.color.item1_color));
this.item2Paint = new Paint(1);
this.item2Paint.setColor(r.getColor(R.color.item2_color));
this.item3Paint = new Paint(1);
this.item3Paint.setColor(r.getColor(R.color.item3_color));
this.item4Paint = new Paint(1);
this.item4Paint.setColor(r.getColor(R.color.item4_color));
this.item5Paint = new Paint(1);
this.item5Paint.setColor(r.getColor(R.color.item5_color));
this.item6Paint = new Paint(1);
this.item6Paint.setColor(r.getColor(R.color.item6_color));
this.item7Paint = new Paint(1);
this.item7Paint.setColor(r.getColor(R.color.item7_color));
this.item8Paint = new Paint(1);
this.item8Paint.setColor(r.getColor(R.color.item8_color));
this.item9Paint = new Paint(1);
this.item9Paint.setColor(r.getColor(R.color.item9_color));
this.item10Paint = new Paint(1);
this.item10Paint.setColor(r.getColor(R.color.item10_color));
this.item11Paint = new Paint(1);
this.item11Paint.setColor(r.getColor(R.color.item11_color));
this.item12Paint = new Paint(1);
this.item12Paint.setColor(r.getColor(R.color.item12_color));
this.item13Paint = new Paint(1);
this.item13Paint.setColor(r.getColor(R.color.item13_color));
this.item14Paint = new Paint(1);
this.item14Paint.setColor(r.getColor(R.color.item14_color));
this.item15Paint = new Paint(1);
this.item15Paint.setColor(r.getColor(R.color.item15_color));
this.lifted = false;
this.selected = -1;
this.lastTheta = 0.0d;
this.timeDiff = 0;
this.oldTime = System.currentTimeMillis();
this.currTime = System.currentTimeMillis();
this.winner = "";
this.resourcePlayer = MediaPlayer.create(getContext(), R.raw.wheel_sound_new);
this.item = "";
this.itemLength = 0.0f;
this.listName = "";
this.textSet = false;
}
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(measure(widthMeasureSpec), measure(heightMeasureSpec));
int width = Math.min(getMeasuredWidth(), getMeasuredHeight());
padding = getPaddingLeft() == 0 ? 0 : getPaddingLeft();
radius = width - padding * 2;
center = width / 2;
}
private int measure(int measureSpec) {
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == 0) {
return 200;
}
return specSize;
}
public boolean withinWheel(float _x, float _y) {
return getRadius() * getRadius() > ((_x - ((float) getPX())) * (_x - ((float) getPX()))) + ((((float) getPY()) - _y) * (((float) getPY()) - _y));
}
public void setList(String _listName) {
this.listName = _listName;
}
public void setRotation(double _rotation) {
Log.e("##_rotation", String.valueOf(_rotation));
this.rotationOffset = _rotation % 360.0d;
}
public double getRotationNumber() {
Log.e("##rotationOffset", String.valueOf(rotationOffset));
return this.rotationOffset;
}
public void setLastTheta(double _lastTheta, float width) {
float offset = 12800.0f / width;
if (_lastTheta < -40.0d) {
_lastTheta = (double) (-offset);
}
if (_lastTheta > 40.0d) {
_lastTheta = (double) offset;
}
this.lastTheta = _lastTheta;
}
public void setItems(List<String> items) {
this.itemNames = items;
}
public int getPX() {
return getMeasuredWidth() / 2;
}
public int getPY() {
return getMeasuredHeight() / 2;
}
public float getRadius() {
return ((float) Math.min(getPX(), getPY())) * 0.8f;
}
protected void onDraw(Canvas canvas) {
float tempAngle = 0;
float sweepAngle = 360 /6;
if (this.itemNames != null) {
int i;
float offSet = 0;
this.px = getMeasuredWidth() / 2;
this.py = getMeasuredHeight() / 2;
if (!this.textSet) {
this.textPaint.setTextSize((float) (getMeasuredWidth() / 25));
this.titlePaint.setTextSize((float) (getMeasuredWidth() / 15));
this.textSet = true;
}
this.radius = ((float) Math.min(this.px, this.py)) * 0.8f;
float incr = 360.0f / ((float) this.itemNames.size());
RectF myCircleBox = new RectF(((float) this.px) - this.radius, ((float) this.py) - this.radius, ((float) this.px) + this.radius, ((float) this.py) + this.radius);
RectF rectF = new RectF(((float) this.px) - (this.radius / 5.0f), ((float) this.py) - (this.radius * 1.1f), ((float) this.px) + (this.radius / 5.0f), ((float) this.py) - (this.radius * 0.6f));
rectF = new RectF((((float) this.px) - (this.radius / 5.0f)) + 5.0f, (((float) this.py) - (this.radius * 1.1f)) + 2.0f, (((float) this.px) + (this.radius / 5.0f)) - 5.0f, (((float) this.py) - (this.radius * 0.6f)) - 12.0f);
Log.e("##rotationOffset", String.valueOf(rotationOffset));
double actualRotation = this.rotationOffset + ((double) ((incr / 2.0f) + 90.0f));
canvas.save();
canvas.rotate((float) this.rotationOffset, (float) this.px, (float) this.py);
for (i = 0; i < this.itemNames.size(); i++) {
Paint itemPaint;
switch (i) {
case MyDBAdapter.KEY_ID_COLUMN /*0*/:
itemPaint = this.item1Paint;
break;
case MyDBAdapter.NAME_COLUMN /*1*/:
itemPaint = this.item2Paint;
break;
case MyDBAdapter.NAME_REF /*2*/:
itemPaint = this.item3Paint;
break;
case 3:
itemPaint = this.item4Paint;
break;
case 4:
itemPaint = this.item5Paint;
break;
case 5:
itemPaint = this.item6Paint;
break;
case 6:
itemPaint = this.item7Paint;
break;
case 7:
itemPaint = this.item8Paint;
break;
case 8:
itemPaint = this.item9Paint;
break;
case 9:
itemPaint = this.item10Paint;
break;
case 10:
itemPaint = this.item11Paint;
break;
case 11:
itemPaint = this.item12Paint;
break;
case 12:
itemPaint = this.item13Paint;
break;
case 13:
itemPaint = this.item14Paint;
break;
case 14:
itemPaint = this.item15Paint;
break;
default:
itemPaint = this.item1Paint;
break;
}
offSet = ((float) i) * (-incr);
canvas.save();
canvas.rotate(offSet, (float) this.px, (float) this.py);
canvas.drawArc(myCircleBox, (-incr) / 2.0f, incr, true, itemPaint);
this.item = ((String) this.itemNames.get(i)).toString();
this.itemLength = (float) ((int) this.textPaint.measureText(this.item));
if (((double) this.itemLength) > ((double) this.radius) * 0.8d) {
this.item = this.item.substring(0, (int) (((double) this.item.length()) * ((((double) this.radius) * 0.8d) / ((double) ((int) this.textPaint.measureText(this.item))))));
this.itemLength = (float) ((int) this.textPaint.measureText(this.item));
}
// canvas.drawText(this.item, (((float) this.px) + (this.radius / 2.0f)) - (this.itemLength / 2.0f), (float) (this.py + ((int) (((double) this.textPaint.measureText("yY")) / 2.5d))), this.textPaint);
Bitmap icon = BitmapFactory.decodeResource(getResources(),R.drawable.ic_laun);
//drawImage(canvas, tempAngle,icon );
tempAngle += sweepAngle;
canvas.restore();
}
for (i = 0; i < this.itemNames.size(); i++) {
offSet = ((float) i) * incr;
canvas.save();
canvas.rotate(offSet, (float) this.px, (float) this.py);
canvas.save();
canvas.rotate(incr / 2.0f, (float) this.px, (float) this.py);
canvas.drawLine(((float) this.px) + this.radius, (float) this.py, (float) this.px, (float) this.py, this.markerPaint);
Bitmap icon =
BitmapFactory.decodeResource(getResources(),R.drawable.ic_laun);
drawImage(canvas, tempAngle,icon );
canvas.restore();
canvas.restore();
}
canvas.restore();
canvas.drawCircle((float) this.px, (float) this.py, this.radius, this.circlePaint);
canvas.drawCircle((float) this.px, (float) this.py, this.radius + (this.circlePaint.getStrokeWidth() * 0.5f), this.rimPaint);
canvas.drawCircle((float) this.px, (float) this.py, 2.0f, this.rimPaint);
canvas.drawCircle((float) this.px, (float) this.py, 1.0f, this.rimPaint);
canvas.drawArc(rectF, 250.0f, 40.0f, true, this.textPaint);
canvas.drawArc(rectF, 250.0f, 40.0f, true, this.pointerPaint);
if (actualRotation < 0.0d) {
actualRotation += 360.0d;
} else if (actualRotation > 360.0d) {
actualRotation -= 360.0d;
}
if (!(this.selected == -1 || this.selected == ((int) (actualRotation / ((double) incr))) || !Prefs.getMusic(getContext()) || this.resourcePlayer == null)) {
if (this.resourcePlayer.isPlaying()) {
this.resourcePlayer.seekTo(0);
} else {
this.resourcePlayer.start();
}
}
this.selected = (int) (actualRotation / ((double) incr));
if (this.lifted) {
this.winner = ((String) this.itemNames.get(this.selected)).toString();
}
canvas.drawText(this.winner, (float) (this.px - (((int) this.titlePaint.measureText(this.winner)) / 2)), (((float) this.py) + this.radius) + ((float) (getMeasuredWidth() / 10)), this.titlePaint);
canvas.drawText(this.listName, (float) (this.px - (((int) this.titlePaint.measureText(this.listName)) / 2)), (((float) this.py) - this.radius) - ((float) (getMeasuredWidth() / 18)), this.titlePaint);
if (this.lifted) {
long currentTimeMillis;
if (this.lastTheta > 0.0d) {
currentTimeMillis = System.currentTimeMillis();
this.currTime = currentTimeMillis;
this.timeDiff = currentTimeMillis - this.oldTime;
this.oldTime = this.currTime;
setRotation(getRotationNumber() + this.lastTheta);
this.lastTheta -= (double) (0.002f * ((float) this.timeDiff));
if (this.lastTheta <= 0.0d) {
this.lifted = false;
Log.e("#finalDone","finalDone"+getRotationNumber());
Log.e("#offset","finalDone"+offSet);
Intent intent=new Intent(mContext, HomeActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP);
mContext.startActivity(intent);
}
} else {
currentTimeMillis = System.currentTimeMillis();
this.currTime = currentTimeMillis;
this.timeDiff = currentTimeMillis - this.oldTime;
this.oldTime = this.currTime;
setRotation(getRotationNumber() + this.lastTheta);
this.lastTheta += (double) (0.002f * ((float) this.timeDiff));
if (this.lastTheta >= 0.0d) {
this.lifted = false;
Log.e("#finalDone","finalDone"+getRotationNumber());
Intent intent=new Intent(mContext, HomeActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP);
mContext.startActivity(intent);
}
}
invalidate();
}
}
}
private void drawImage(Canvas canvas, float tempAngle, Bitmap bitmap) {
//get every arc img width and angle
int mWheelItemssize=6;
int imgWidth = (int)radius / 6;
float angle = (float) ((tempAngle + 360 / mWheelItemssize / 2) * Math.PI / 180);
//calculate x and y
int x = (int) (center + (int)radius / 2 / 2 * Math.cos(angle));
int y = (int) (center + (int) radius / 2 / 2 * Math.sin(angle));
Rect rect = new Rect(x - imgWidth /2, y - imgWidth / 2, x + imgWidth / 2, y + imgWidth / 2);
Bitmap rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), null, true);
canvas.drawBitmap(bitmap, null, rect, null);
}
private void drawImage1(Canvas canvas, float tmpAngle, Bitmap bitmap) {
int imgWidth = (int) (radius / itemNames.size());
float angle = (float) ((tmpAngle + 360 / itemNames.size() / 2) * Math.PI / 180);
int x = (int) (center + radius / 2 / 2 * Math.cos(angle));
int y = (int) (center + radius / 2 / 2 * Math.sin(angle));
Rect rect = new Rect(x - imgWidth/2, y - imgWidth/2, x + imgWidth/2, y + imgWidth/2);
canvas.drawBitmap(bitmap, null, rect, null);
}
void OnDestroy() {
if (this.resourcePlayer != null) {
this.resourcePlayer.release();
}
}
public void autoSpin(float seed) {
if (seed >= 20.0f) {
seed = 15.0f;
}
seed = 8.0f;
this.oldTime = System.currentTimeMillis();
this.currTime = System.currentTimeMillis();
Log.e("##oldTime", String.valueOf(System.currentTimeMillis()));
Log.e("##Random", String.valueOf((new Random().nextFloat())));
Log.e("##Random", String.valueOf((new Random().nextFloat())));
int randomno=3;
this.lastTheta = (double) ((randomno * seed));
Log.e("##lastTheta", String.valueOf(lastTheta));
this.lifted = true;
invalidate();
}
}
HomeActivity
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.autoSpinButton:
// wheelView.rotateWheelTo(wheelView,3);
autoSpinButton.setEnabled(false);
Log.e("###Seed", String.valueOf(20.0f * (320.0f / width)));
wheelView.autoSpin(5.0);
break;
}
}
main Layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.spin.wheel.widgets.WheelView
android:id="#+id/wheelView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/backrepeat"/>
<Button
android:id="#+id/autoSpinButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:layout_centerInParent="true"
android:text="SPIN" />
</RelativeLayout>
Please Help
i have followed this tutorial to zoom in imageview on touch but i have an activity that have 15 images and when i click on any one image it will open new Activity and will zoom in that clicked image on new Activity so my question is
How can i pass clicked image src to nextActivity so that my single method will be applicable to zoom in for all images.
On new Activity (Zoom in) when i clicked on it how can i zoom out that image again.
I have followed this:Zoom in
Its successfully zoom in an imageview but i have no idea how to write code for zoom out.Can someone please help me on this task.
Any Tutorials will be appreciated but link must contain same code as it is in this url with some few changes for zoom out
public class TouchImageView extends ImageView {
Matrix matrix;
static final int NONE = 0;
static final int DRAG = 1;
static int ZOOM = 2;
static int mode = NONE;
public int isundo = 0;
PointF last = new PointF();
PointF start = new PointF();
float minScale = 0f;
float maxScale = 1f;
float[] m;
int viewWidth, viewHeight;
static final int CLICK = 3;
float saveScale = 1f;
protected float origWidth, origHeight;
int oldMeasuredWidth, oldMeasuredHeight;
float bmWidth, bmHeight;
ScaleGestureDetector mScaleDetector;
Context context;
public TouchImageView(Context context) {
super(context);
if (isundo == 0) {
sharedConstructing(context);
}
}
public TouchImageView(Context context, AttributeSet attrs) {
super(context, attrs);
if (isundo == 0) {
sharedConstructing(context);
}
}
private void sharedConstructing(Context context) {
super.setClickable(true);
this.context = context;
mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
matrix = new Matrix();
m = new float[9];
setImageMatrix(matrix);
setScaleType(ScaleType.MATRIX);
setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
mScaleDetector.onTouchEvent(event);
PointF curr = new PointF(event.getX(), event.getY());
if (isundo == 0) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
last.set(curr);
start.set(last);
mode = DRAG;
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG) {
float deltaX = curr.x - last.x;
float deltaY = curr.y - last.y;
matrix.postTranslate(deltaX, deltaY);
fixTrans();
last.set(curr.x, curr.y);
}
break;
case MotionEvent.ACTION_UP:
mode = NONE;
int xDiff = (int) Math.abs(curr.x - start.x);
int yDiff = (int) Math.abs(curr.y - start.y);
if (xDiff < CLICK && yDiff < CLICK)
performClick();
break;
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
break;
}
}
setImageMatrix(matrix);
invalidate();
return true; // indicate event was handled
}
});
}
public void stopInterceptEvent() {
getParent().requestDisallowInterceptTouchEvent(true);
}
public void startInterceptEvent() {
getParent().requestDisallowInterceptTouchEvent(false);
}
#Override
public void setImageBitmap(Bitmap bm) {
super.setImageBitmap(bm);
if (bm != null) {
origWidth = bm.getWidth();
origHeight = bm.getHeight();
}
}
public void setMaxZoom(float x) {
maxScale = x;
}
private class ScaleListener extends
ScaleGestureDetector.SimpleOnScaleGestureListener {
#Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
mode = ZOOM;
return true;
}
#Override
public boolean onScale(ScaleGestureDetector detector) {
float mScaleFactor = detector.getScaleFactor();
float origScale = saveScale;
saveScale *= mScaleFactor;
if (saveScale > maxScale) {
saveScale = maxScale;
mScaleFactor = maxScale / origScale;
} else if (saveScale < minScale) {
saveScale = minScale;
mScaleFactor = minScale / origScale;
}
if (origWidth * saveScale <= viewWidth
|| origHeight * saveScale <= viewHeight)
matrix.postScale(mScaleFactor, mScaleFactor, viewWidth / 2,
viewHeight / 2);
else
matrix.postScale(mScaleFactor, mScaleFactor,
detector.getFocusX(), detector.getFocusY());
fixTrans();
return true;
}
}
void fixTrans() {
matrix.getValues(m);
float transX = m[Matrix.MTRANS_X];
float transY = m[Matrix.MTRANS_Y];
float fixTransX = getFixTrans(transX, viewWidth, origWidth * saveScale);
float fixTransY = getFixTrans(transY, viewHeight, origHeight
* saveScale);
if (fixTransX != 0 || fixTransY != 0)
matrix.postTranslate(fixTransX, fixTransY);
}
float getFixTrans(float trans, float viewSize, float contentSize) {
float minTrans, maxTrans;
if (contentSize <= viewSize) {
minTrans = 0;
maxTrans = viewSize - contentSize;
} else {
minTrans = viewSize - contentSize;
maxTrans = 0;
}
if (trans < minTrans)
return -trans + minTrans;
if (trans > maxTrans)
return -trans + maxTrans;
return 0;
}
float getFixDragTrans(float delta, float viewSize, float contentSize) {
if (contentSize <= viewSize) {
return 0;
}
return delta;
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
viewWidth = MeasureSpec.getSize(widthMeasureSpec);
viewHeight = MeasureSpec.getSize(heightMeasureSpec);
//
// Rescales image on rotation
//
if (oldMeasuredHeight == viewWidth && oldMeasuredHeight == viewHeight
|| viewWidth == 0 || viewHeight == 0)
return;
oldMeasuredHeight = viewHeight;
oldMeasuredWidth = viewWidth;
if (saveScale == 1) {
// Fit to screen.
float scale;
Drawable drawable = getDrawable();
if (drawable == null || drawable.getIntrinsicWidth() == 0
|| drawable.getIntrinsicHeight() == 0)
return;
int bmWidth = drawable.getIntrinsicWidth();
int bmHeight = drawable.getIntrinsicHeight();
float scaleX = (float) viewWidth / (float) bmWidth;
float scaleY = (float) viewHeight / (float) bmHeight;
scale = Math.min(scaleX, scaleY);
matrix.setScale(scale, scale);
// Center the image
float redundantYSpace = (float) viewHeight
- (scale * (float) bmHeight);
float redundantXSpace = (float) viewWidth
- (scale * (float) bmWidth);
redundantYSpace /= (float) 2;
redundantXSpace /= (float) 2;
matrix.postTranslate(redundantXSpace, redundantYSpace);
origWidth = viewWidth - 2 * redundantXSpace;
origHeight = viewHeight - 2 * redundantYSpace;
setImageMatrix(matrix);
}
fixTrans();
}
}
use this way like ::---->>>
TouchImageView iv = new TouchImageView(getApplicationContext());
iv.setImageBitmap(editedImage);
layout.addView(iv);
I am implementing an app for getting the correct x and y location of the image-view and x and y coordinates of an image-view when I move the position of images on the screen. When I run the app and when I move my image-view it will get only 0 and 1. Is there a way for find out the x and y location?
Here is my Main-activity class:
public class MainActivity extends Activity{
static final int NONE = 0;
static final int DRAG = 1;
static final int ZOOM = 2;
int mode = NONE;
Matrix matrix = new Matrix();
Matrix savedMatrix = new Matrix();
PointF start = new PointF();
PointF mid = new PointF();
float oldDist = 1f;
int[] location = new int[4];
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ImageView image = (ImageView) findViewById(R.id.ImageViewOne);
final Bitmap icon = BitmapFactory.decodeResource(this.getResources(),
R.drawable.yellowrose);
image.setImageBitmap(icon);
image.setOnTouchListener(new View.OnTouchListener()
{
public boolean onTouch(View v, MotionEvent event)
{
final ImageView view = (ImageView) v;
switch (event.getAction() & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_DOWN:
savedMatrix.set(matrix);
start.set(event.getX(), event.getY());
mode = DRAG;
System.out.println("mode = drag");
RectF r = new RectF();
matrix.mapRect(r);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
System.out.println("mode = none = " + mode);
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG)
{
matrix.set(savedMatrix);
matrix.postTranslate(event.getX() - start.x,
event.getY() - start.y);
}
else if (mode == ZOOM)
{
float newDist = spacing(event);
if (newDist > 10f)
{
matrix.set(savedMatrix);
float scale = newDist / oldDist;
System.out.println("scale " + scale);
matrix.postScale(scale, scale, mid.x, mid.y);
}
}
break;
case MotionEvent.ACTION_POINTER_DOWN:
oldDist = spacing(event);
if (oldDist > 10f)
{
savedMatrix.set(matrix);
midPoint(mid, event);
mode = ZOOM;
System.out.println("mode " + mode);
}
break;
}
// Perform the transformation
view.setImageMatrix(matrix);
return true;
}
});
}
private float spacing(MotionEvent event)
{
float x = event.getRawX() - event.getRawX();
System.out.println("spacing x" + x);
float y = event.getRawY() - event.getRawY();
System.out.println("spacing y" + y);
return FloatMath.sqrt(x * x + y * y);
}
private void midPoint(PointF point, MotionEvent event)
{
float x = event.getRawX() + event.getRawX();
System.out.println("midpoint x" + x);
float y = event.getRawY() + event.getRawY();
System.out.println("midpoint y" + y);
point.set(x / 2, y / 2);
}
}
I am using View.getLocationOnScreen(int[]) to get X and Y of a view relative to its parent/screen:
int[] posXY = new int[2];
myView.getLocationOnScreen(posXY);
int x = posXY[0];
int y = posXY[1];
i am working on a project where i need to add pins on image view as shown in below image.
how could we do this.
i successfully created a zoomable image view using
TouchImageview.java
class TouchImageView extends ImageView {
Matrix matrix = 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 last = new PointF();
PointF start = new PointF();
float minScale = 1f;
float maxScale = 3f;
float[] m;
float redundantXSpace, redundantYSpace;
float width, height;
static final int CLICK = 3;
float saveScale = 1f;
float right, bottom, origWidth, origHeight, bmWidth, bmHeight;
ScaleGestureDetector mScaleDetector;
Context context;
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
public TouchImageView(Context context) {
super(context);
super.setClickable(true);
this.context = context;
mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
matrix.setTranslate(1f, 1f);
m = new float[9];
setImageMatrix(matrix);
setScaleType(ScaleType.MATRIX);
setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
mScaleDetector.onTouchEvent(event);
Log.e("Deepak", "X" + event.getRawX());
Log.e("Deepak", "Y" + event.getRawY());
matrix.getValues(m);
float x = m[Matrix.MTRANS_X];
float y = m[Matrix.MTRANS_Y];
PointF curr = new PointF(event.getX(), event.getY());
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
last.set(event.getX(), event.getY());
start.set(last);
mode = DRAG;
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG) {
float deltaX = curr.x - last.x;
float deltaY = curr.y - last.y;
float scaleWidth = Math.round(origWidth * saveScale);
float scaleHeight = Math.round(origHeight * saveScale);
if (scaleWidth < width) {
deltaX = 0;
if (y + deltaY > 0)
deltaY = -y;
else if (y + deltaY < -bottom)
deltaY = -(y + bottom);
} else if (scaleHeight < height) {
deltaY = 0;
if (x + deltaX > 0)
deltaX = -x;
else if (x + deltaX < -right)
deltaX = -(x + right);
} else {
if (x + deltaX > 0)
deltaX = -x;
else if (x + deltaX < -right)
deltaX = -(x + right);
if (y + deltaY > 0)
deltaY = -y;
else if (y + deltaY < -bottom)
deltaY = -(y + bottom);
}
matrix.postTranslate(deltaX, deltaY);
last.set(curr.x, curr.y);
}
break;
case MotionEvent.ACTION_UP:
mode = NONE;
int xDiff = (int) Math.abs(curr.x - start.x);
int yDiff = (int) Math.abs(curr.y - start.y);
if (xDiff < CLICK && yDiff < CLICK)
performClick();
break;
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
break;
}
setImageMatrix(matrix);
invalidate();
return true; // indicate event was handled
}
});
}
#Override
public void setImageBitmap(Bitmap bm) {
super.setImageBitmap(bm);
bmWidth = bm.getWidth();
bmHeight = bm.getHeight();
}
public void setMaxZoom(float x)
{
maxScale = x;
}
private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
#Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
mode = ZOOM;
return true;
}
#Override
public boolean onScale(ScaleGestureDetector detector) {
float mScaleFactor = (float)Math.min(Math.max(.95f, detector.getScaleFactor()), 1.05);
float origScale = saveScale;
saveScale *= mScaleFactor;
if (saveScale > maxScale) {
saveScale = maxScale;
mScaleFactor = maxScale / origScale;
} else if (saveScale < minScale) {
saveScale = minScale;
mScaleFactor = minScale / origScale;
}
right = width * saveScale - width - (2 * redundantXSpace * saveScale);
bottom = height * saveScale - height - (2 * redundantYSpace * saveScale);
if (origWidth * saveScale <= width || origHeight * saveScale <= height) {
matrix.postScale(mScaleFactor, mScaleFactor, width / 2, height / 2);
if (mScaleFactor < 1) {
matrix.getValues(m);
float x = m[Matrix.MTRANS_X];
float y = m[Matrix.MTRANS_Y];
if (mScaleFactor < 1) {
if (Math.round(origWidth * saveScale) < width) {
if (y < -bottom)
matrix.postTranslate(0, -(y + bottom));
else if (y > 0)
matrix.postTranslate(0, -y);
} else {
if (x < -right)
matrix.postTranslate(-(x + right), 0);
else if (x > 0)
matrix.postTranslate(-x, 0);
}
}
}
} else {
matrix.postScale(mScaleFactor, mScaleFactor, detector.getFocusX(), detector.getFocusY());
matrix.getValues(m);
float x = m[Matrix.MTRANS_X];
float y = m[Matrix.MTRANS_Y];
if (mScaleFactor < 1) {
if (x < -right)
matrix.postTranslate(-(x + right), 0);
else if (x > 0)
matrix.postTranslate(-x, 0);
if (y < -bottom)
matrix.postTranslate(0, -(y + bottom));
else if (y > 0)
matrix.postTranslate(0, -y);
}
}
return true;
}
}
#Override
protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec)
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = MeasureSpec.getSize(widthMeasureSpec);
height = MeasureSpec.getSize(heightMeasureSpec);
//Fit to screen.
float scale;
float scaleX = (float)width / (float)bmWidth;
float scaleY = (float)height / (float)bmHeight;
scale = Math.min(scaleX, scaleY);
matrix.setScale(scale, scale);
setImageMatrix(matrix);
saveScale = 1f;
// Center the image
redundantYSpace = (float)height - (scale * (float)bmHeight) ;
redundantXSpace = (float)width - (scale * (float)bmWidth);
redundantYSpace /= (float)2;
redundantXSpace /= (float)2;
matrix.postTranslate(redundantXSpace, redundantYSpace);
origWidth = width - 2 * redundantXSpace;
origHeight = height - 2 * redundantYSpace;
right = width * saveScale - width - (2 * redundantXSpace * saveScale);
bottom = height * saveScale - height - (2 * redundantYSpace * saveScale);
setImageMatrix(matrix);
}
}
now i need to add markers on it.
any help for it.
i found my answer here https://github.com/catchthecows/AndroidImageMap
An implementation of an HTML map like element in an Android View:
Supports images as drawable or bitmap in layout
Allows for a list of area tags in xml
Enables use of cut and paste HTML area tags to a resource xml (ie, the ability to take an HTML map - and image and use it with minimal editing)
Supports panning if the image is larger than the device screen
Supports pinch-zoom
Supports callbacks when an area is tapped.
Supports showing annotations as bubble text and provide callback if the bubble is tapped
I have used AndroidImageMap but i don't like how it zooms the image, and you don't have facilities to add custom views as clickable areas.
Checkout this example project https://github.com/jzafrilla/AndroidImageHostpot I have used https://github.com/chrisbanes/PhotoView/ to get Zoom and Pan functionality.
Hope this helps...(to me, absolutely yes)
I have good working TouchImageView and i want to know how does it work in a code :
What i just want to do is be able to pinch to zoom, or use double tap to zoom on any imageview i choose, and when i zoom back i return to the original size of the image.
TouchImageView.java :
public class TouchImageView extends ImageView {
Matrix matrix = new Matrix();
static final int NONE = 0;
static final int DRAG = 1;
static final int ZOOM = 2;
int mode = NONE;
PointF last = new PointF();
PointF start = new PointF();
float minScale = 1f;
float maxScale = 3f;
float[] m;
float redundantXSpace, redundantYSpace;
float width, height;
static final int CLICK = 3;
float saveScale = 1f;
float right, bottom, origWidth, origHeight, bmWidth, bmHeight;
ScaleGestureDetector mScaleDetector;
Context context;
public TouchImageView(Context context) {
super(context);
super.setClickable(true);
this.context = context;
mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
matrix.setTranslate(1f, 1f);
m = new float[9];
setImageMatrix(matrix);
setScaleType(ScaleType.MATRIX);
setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
mScaleDetector.onTouchEvent(event);
matrix.getValues(m);
float x = m[Matrix.MTRANS_X];
float y = m[Matrix.MTRANS_Y];
PointF curr = new PointF(event.getX(), event.getY());
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
last.set(event.getX(), event.getY());
start.set(last);
mode = DRAG;
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG) {
float deltaX = curr.x - last.x;
float deltaY = curr.y - last.y;
float scaleWidth = Math.round(origWidth * saveScale);
float scaleHeight = Math.round(origHeight * saveScale);
if (scaleWidth < width) {
deltaX = 0;
if (y + deltaY > 0)
deltaY = -y;
else if (y + deltaY < -bottom)
deltaY = -(y + bottom);
} else if (scaleHeight < height) {
deltaY = 0;
if (x + deltaX > 0)
deltaX = -x;
else if (x + deltaX < -right)
deltaX = -(x + right);
} else {
if (x + deltaX > 0)
deltaX = -x;
else if (x + deltaX < -right)
deltaX = -(x + right);
if (y + deltaY > 0)
deltaY = -y;
else if (y + deltaY < -bottom)
deltaY = -(y + bottom);
}
matrix.postTranslate(deltaX, deltaY);
last.set(curr.x, curr.y);
}
break;
case MotionEvent.ACTION_UP:
mode = NONE;
int xDiff = (int) Math.abs(curr.x - start.x);
int yDiff = (int) Math.abs(curr.y - start.y);
if (xDiff < CLICK && yDiff < CLICK)
performClick();
break;
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
break;
}
setImageMatrix(matrix);
invalidate();
return true; // indicate event was handled
}
});
}
#Override
public void setImageBitmap(Bitmap bm) {
super.setImageBitmap(bm);
bmWidth = bm.getWidth();
bmHeight = bm.getHeight();
}
public void setMaxZoom(float x)
{
maxScale = x;
}
private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
#Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
mode = ZOOM;
return true;
}
#Override
public boolean onScale(ScaleGestureDetector detector) {
float mScaleFactor = (float)Math.min(Math.max(.95f, detector.getScaleFactor()), 1.05);
float origScale = saveScale;
saveScale *= mScaleFactor;
if (saveScale > maxScale) {
saveScale = maxScale;
mScaleFactor = maxScale / origScale;
} else if (saveScale < minScale) {
saveScale = minScale;
mScaleFactor = minScale / origScale;
}
right = width * saveScale - width - (2 * redundantXSpace * saveScale);
bottom = height * saveScale - height - (2 * redundantYSpace * saveScale);
if (origWidth * saveScale <= width || origHeight * saveScale <= height) {
matrix.postScale(mScaleFactor, mScaleFactor, width / 2, height / 2);
if (mScaleFactor < 1) {
matrix.getValues(m);
float x = m[Matrix.MTRANS_X];
float y = m[Matrix.MTRANS_Y];
if (mScaleFactor < 1) {
if (Math.round(origWidth * saveScale) < width) {
if (y < -bottom)
matrix.postTranslate(0, -(y + bottom));
else if (y > 0)
matrix.postTranslate(0, -y);
} else {
if (x < -right)
matrix.postTranslate(-(x + right), 0);
else if (x > 0)
matrix.postTranslate(-x, 0);
}
}
}
} else {
matrix.postScale(mScaleFactor, mScaleFactor, detector.getFocusX(), detector.getFocusY());
matrix.getValues(m);
float x = m[Matrix.MTRANS_X];
float y = m[Matrix.MTRANS_Y];
if (mScaleFactor < 1) {
if (x < -right)
matrix.postTranslate(-(x + right), 0);
else if (x > 0)
matrix.postTranslate(-x, 0);
if (y < -bottom)
matrix.postTranslate(0, -(y + bottom));
else if (y > 0)
matrix.postTranslate(0, -y);
}
}
return true;
}
}
#Override
protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec)
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = MeasureSpec.getSize(widthMeasureSpec);
height = MeasureSpec.getSize(heightMeasureSpec);
//Fit to screen.
float scale;
float scaleX = (float)width / (float)bmWidth;
float scaleY = (float)height / (float)bmHeight;
scale = Math.min(scaleX, scaleY);
matrix.setScale(scale, scale);
setImageMatrix(matrix);
saveScale = 1f;
// Center the image
redundantYSpace = (float)height - (scale * (float)bmHeight) ;
redundantXSpace = (float)width - (scale * (float)bmWidth);
redundantYSpace /= (float)2;
redundantXSpace /= (float)2;
matrix.postTranslate(redundantXSpace, redundantYSpace);
origWidth = width - 2 * redundantXSpace;
origHeight = height - 2 * redundantYSpace;
right = width * saveScale - width - (2 * redundantXSpace * saveScale);
bottom = height * saveScale - height - (2 * redundantYSpace * saveScale);
setImageMatrix(matrix);
}
}
To use is i created a private class :
private class CreateImage extends AsyncTask<String, Void, Drawable> {
protected void onPreExecute() {
}
protected Drawable doInBackground(String... urls) {
InputStream is;
Drawable d = null ;
try {
is = (InputStream)new URL(urls[0]).getContent();
d = Drawable.createFromStream(is, "Image");
return d;
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return d;
}
protected void onPostExecute(Drawable d) {
touch.setMaxZoom(4f);
touch.setImageDrawable(d);
setContentView(touch);
}
}
public void createUrlImage(String url){
new CreateImage().execute(url);
}
and in the onCreate() i put createUrlImage(url).
I modified TouchImageView by adding :
public void setImageDrawable(Drawable dr) {
super.setImageDrawable(dr);
bmWidth = dr.getIntrinsicWidth();
bmHeight = dr.getIntrinsicHeight();
}
EDIT: Double Tap Zoom, Fling and other features have been added to TouchImageView since I originally answered this question. You can check it out on github here.
I added some usage details to the original post here. The code already has pinch zoom and panning, along with boundaries. Also, zooming out will return you to the original sized image.
Adding double tap zoom will take more work. You'll have to use a GestureDetector and override onDoubleTap and onSingleTapConfirmed. You'll then want to make sure you pass your touch events to gestureDetector, without interfering with the rest of the code (see how events are passed to mScaleDetector at the beginning of onTouch). You'll want to get rid of the call to performClick() in ACTION_UP and instead place it in onSingleTapConfirmed. You can check this answer for some skeletal code to get you started in implementing GestureDetector.
Let me know if you manage to get double tap zoom solid and I'll add your changes to the original post and the Github repo.