1

我正在尝试实现双击和捏缩放活动。我为第一个代码写了一些代码,但它似乎不起作用(我现在只能使用 android 模拟器进行 eclipse。所以我不确定我的结果是否正确)

无论如何,我无法理解我做错了什么。我肯定忘记了什么。

这是我的代码:

public class ImageZoomView extends View implements OnGestureListener {

private static final int SCALING_FACTOR = 50;
private final int LANDSCAPE = 1;
private GestureDetector gestureDetector;
private Drawable image = null;
private int scalefactor = 0;
private int orientation;
private int zoomCtr = 0;
private long lastTouchTime = 0;
private int winX, winY, imageX, imageY, scrollX = 0, scrollY = 0, left,
top, bottom, right;

public ImageZoomView(Context context, int orientation) {
            super(context);
            setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
                    LayoutParams.FILL_PARENT));
            this.orientation = orientation;
            gestureDetector = new GestureDetector(this);
        }

    public void setImage(Drawable bitmap, Activity activity) {
        image = bitmap;
        imageSetting(activity);
    }

    public void setImage(Bitmap bitmap, Activity activity) {
        image = new BitmapDrawable(bitmap).getCurrent();
        imageSetting(activity);
    }

    /**
     * Works in both landscape and portrait mode.
     */
    private void imageSetting(Activity activity) {
        scrollX = scrollY = 0;
        scalefactor = 0;
        imageX = winX = activity.getWindow().getWindowManager()
                .getDefaultDisplay().getWidth();
        imageY = winY = activity.getWindow().getWindowManager()
                .getDefaultDisplay().getHeight();
        if (orientation == LANDSCAPE) {
            imageX = 3 * imageY / 4;
        }
        calculatePos();
    }

    public void calculatePos() {
        int tempx, tempy;
        tempx = imageX + imageX * scalefactor / 100;
        tempy = imageY + imageY * scalefactor / 100;
        left = (winX - tempx) / 2;
        top = (winY - tempy) / 2;
        right = (winX + tempx) / 2;
        bottom = (winY + tempy) / 2;
        invalidate();
    }

    /**
     * Redraws the bitmap when zoomed or scrolled.
     */
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        if (image == null)
            return;

        image.setBounds(left + scrollX, top + scrollY, right + scrollX, bottom
                + scrollY);
        image.draw(canvas);
    }

    public void zoomIn() {
        scalefactor += SCALING_FACTOR;
        calculatePos();
    }

    public void zoomOut() {
        if (scalefactor == 0)
            return;
        scrollX = scrollY = 0;
        scalefactor -= SCALING_FACTOR;
        calculatePos();
    }

    public void scroll(int x, int y) {
        scrollX += x / 5;
        scrollY += y / 5;
        if (scrollX + left > 0) {
            scrollX = 0 - left;
        } else if (scrollX + right < winX) {
            scrollX = winX - right;
        }
        if (scrollY + top > 0) {
            scrollY = 0 - top;
        } else if (scrollY + bottom < winY) {
            scrollY = winY - bottom;
        }
        invalidate();
    }

    @Override
    public boolean onTouchEvent(MotionEvent me) {
        boolean onTouchEvent = gestureDetector.onTouchEvent(me);
        return onTouchEvent;
    }

    @Override
    public boolean onDown(MotionEvent arg0) {
        long thisTime = arg0.getEventTime();
        if (thisTime - lastTouchTime < 250) {
            lastTouchTime = -1;
            onDoubleTap();
            return true;
        }
        lastTouchTime = thisTime;
        return true;
    }

    @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
                float distanceY) {
            if (zoomCtr == 0)
                return false;
            scroll((int) (e2.getX() - e1.getX()), (int) (e2.getY() - e1.getY()));
            return true;
        }

        private void onDoubleTap() {
            if (zoomCtr == 0) {
                zoomCtr++;
                zoomIn();
                return;
            }
            zoomCtr--;
            zoomOut();
    }
}

这就是我所说的活动:

public class FullScreenPhoto extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_full_screen_photo);
    Intent intent = getIntent();
    String path = intent.getStringExtra("Path");
    ImageView img = (ImageView)findViewById(R.id.photo);
    img.setImageURI(Uri.parse(path));

    ImageZoomView imageView = new ImageZoomView(
            this,getWindow().getWindowManager().getDefaultDisplay().getOrientation());
    this.setContentView(imageView);
    }
}

它在屏幕上显示完整的图像,但是当点击它时,什么也没有发生。

4

2 回答 2

3

伟大的创建一个名为ZoomFunctionality

变焦功能

package com.androidhive.work;

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;

public class ZoomFunctionality 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 ZoomFunctionality(Context context) {
    super(context);
    sharedConstructing(context);
}

public ZoomFunctionality(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() {

        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 = detector.getScaleFactor();
        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);
}
}

现在,当您想调用ZoomFunctionalityfrom时,Activity只需编写以下语句

BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
Bitmap bmp = BitmapFactory.decodeFile(filename, options);


ZoomFunctionality img = new ZoomFunctionality(this);
img.setImageBitmap(bmp);
img.setMaxZoom(4f);
setContentView(img);

注意
bmp:您想要缩放功能的位图图像吗?
this:建议您使用 Activity.this
不需要使用 BitmapFactoryOptions,但需要从文件名解码

于 2013-06-24T21:40:00.453 回答
1

TouchImageView.java

package com.animation.sound;

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(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();
    }
}

把这行放在 MainActivity.java 类中......

TouchImageView imgView;
imgView = (TouchImageView) findViewById(R.id.imgmstlv);

和更多信息。按照这个链接放大和缩小

于 2014-12-30T07:50:08.923 回答