Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.example.poweruser.fcemsandroid;
- import android.content.Context;
- import android.graphics.Matrix;
- import android.graphics.PointF;
- 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.ImageView;
- public class TouchImageView extends ImageView {
- Matrix 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;
- int viewWidth, viewHeight;
- static final int CLICK = 3;
- float saveScale = 1f;
- protected float origWidth, origHeight;
- int oldMeasuredWidth, oldMeasuredHeight;
- ScaleGestureDetector mScaleDetector;
- Context context;
- public TouchImageView() {}
- 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 = 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());
- 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;
- float fixTransX = getFixDragTrans(deltaX, viewWidth, origWidth * saveScale);
- float fixTransY = getFixDragTrans(deltaY, viewHeight, origHeight * saveScale);
- matrix.postTranslate(fixTransX, fixTransY);
- 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 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();
- Log.d("bmSize", "bmWidth: " + bmWidth + " bmHeight : " + bmHeight);
- 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();
- }
Add Comment
Please, Sign In to add comment