【问题标题】:"Zoom In/out " image on Button Click in Android?Android中按钮单击上的“放大/缩小”图像?
【发布时间】:2014-02-20 06:26:07
【问题描述】:

我是 Android 的新手。我已经关注了这个问题,我成功地缩放了一张图片,这段代码运行良好,有人可以帮我写一下如何在按钮点击时为 zoomin zoomout 编写代码。我不知道如何完成这个任务

这是我关注的教程Tutorial Zoom Image,也关注“Salman's Ayub Answer

它工作正常,但我未能在放大和缩小图像时应用比例因子

【问题讨论】:

  • 您有兴趣通过 xml 来完成这项工作吗?
  • no id nt 想要使用 xml 我已经提到了我想要通过定义比例来完成的教程
  • 请检查答案,谢谢。

标签: java android zooming


【解决方案1】:

尝试使用PhotoView。我认为它可以满足您的要求。

【讨论】:

    【解决方案2】:

    您需要将这 2 个方法添加到您的 TouchImageView 类中:

    public void zoomIn() {
        oldScale = saveScale;
    
        if(saveScale<=maxScale)
        {
            saveScale += .5;
            matrix.setScale(saveScale, saveScale);
            setImageMatrix(matrix);
            invalidate();
    
            // Center the image
            // Center the image
            if(bmHeight>bmWidth)
            {
            redundantXSpace = width - (saveScale * bmWidth);
            redundantXSpace /= 2;
            }
            else 
            {
                redundantYSpace = height - (saveScale * bmHeight) ;
                redundantYSpace /= 2;
            }
    
            matrix.postTranslate(redundantXSpace , redundantYSpace );
            setImageMatrix(matrix);
            invalidate();
        }
    }
    
    public void zoomOut() {
    
        if(saveScale>=minScale)
        {
            saveScale -= .5;
            matrix.setScale(saveScale, saveScale);
            setImageMatrix(matrix);
            invalidate();
    
            // Center the image
            if(bmHeight>bmWidth)
            {
            redundantXSpace = width - (saveScale * bmWidth);
            redundantXSpace /= 2;
            }
            else 
            {
                redundantYSpace = height - (saveScale * bmHeight) ;
                redundantYSpace /= 2;
            }
            matrix.postTranslate(redundantXSpace , redundantYSpace );
            setImageMatrix(matrix);
            invalidate();
        }
    }
    

    这是完整的TouchImageView 类代码,以及这两个方法:

    public class TouchImageView extends ImageView {
    
    public 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;
    static final int CLICK = 3;
    int mode = NONE;
    float oldScale = 1.0f;
    
    // Remember some things for zooming
    PointF last = new PointF();
    PointF start = new PointF();
    float minScale = 1f;
    float maxScale = 4f;
    float[] m;
    
    float redundantXSpace, redundantYSpace;   
    float width, height;
    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_POINTER_DOWN:
                    last.set(event.getX(), event.getY());
                    start.set(last);
                    mode = ZOOM;
                    break;
                case MotionEvent.ACTION_MOVE:
                    if (mode == ZOOM || (mode == DRAG && saveScale > minScale)) {
                        Log.d("******", "ZOOM OR 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);
                    }else if(mode == DRAG && saveScale == minScale) {
                        Log.d("******", "DRAG");
                    }
                    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 = detector.getScaleFactor();//(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 =  width / bmWidth;
        float scaleY = height / bmHeight;
        scale = Math.min(scaleX, scaleY);
        matrix.setScale(scale, scale);
        setImageMatrix(matrix);
        saveScale = 1f;
    
        // Center the image
        redundantYSpace = height - (scale * bmHeight) ;
        redundantXSpace = width - (scale * bmWidth);
        redundantYSpace /= 2;
        redundantXSpace /= 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);
    }
    
    public TouchImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        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_POINTER_DOWN:
                    last.set(event.getX(), event.getY());
                    start.set(last);
                    mode = ZOOM;
                    break;
                case MotionEvent.ACTION_MOVE:
                    if (mode == ZOOM || (mode == DRAG && saveScale > minScale)) {
                        Log.d("******", "ZOOM OR 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);
                    }else if(mode == DRAG && saveScale == minScale) {
                        Log.d("******", "DRAG");
                    }
                    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 TouchImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        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_POINTER_DOWN:
                    last.set(event.getX(), event.getY());
                    start.set(last);
                    mode = ZOOM;
                    break;
                case MotionEvent.ACTION_MOVE:
                    if (mode == ZOOM || (mode == DRAG && saveScale > minScale)) {
                        Log.d("******", "ZOOM OR 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);
                    }else if(mode == DRAG && saveScale == minScale) {
                        Log.d("******", "DRAG");
                    }
                    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 zoomIn() {
        oldScale = saveScale;
    
        if(saveScale<=maxScale)
        {
            saveScale += .5;
            matrix.setScale(saveScale, saveScale);
            setImageMatrix(matrix);
            invalidate();
    
            // Center the image
            // Center the image
            if(bmHeight>bmWidth)
            {
            redundantXSpace = width - (saveScale * bmWidth);
            redundantXSpace /= 2;
            }
            else 
            {
                redundantYSpace = height - (saveScale * bmHeight) ;
                redundantYSpace /= 2;
            }
    
            matrix.postTranslate(redundantXSpace , redundantYSpace );
            setImageMatrix(matrix);
            invalidate();
        }
    }
    
    public void zoomOut() {
    
        if(saveScale>=minScale)
        {
            saveScale -= .5;
            matrix.setScale(saveScale, saveScale);
            setImageMatrix(matrix);
            invalidate();
    
            // Center the image
            if(bmHeight>bmWidth)
            {
            redundantXSpace = width - (saveScale * bmWidth);
            redundantXSpace /= 2;
            }
            else 
            {
                redundantYSpace = height - (saveScale * bmHeight) ;
                redundantYSpace /= 2;
            }
            matrix.postTranslate(redundantXSpace , redundantYSpace );
            setImageMatrix(matrix);
            invalidate();
        }
    }
    } 
    

    如何在放大/缩小按钮中使用它们:

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        setContentView(R.layout.LAYOUT_NAME);
    
        Button zoonIn = (Button)findViewById(R.id.ZOOM_IN_BUTTON_ID);
        Button zoonOut = (Button)findViewById(R.id.ZOOM_OUT_BUTTON_ID);
    
        final TouchImageView touch = (TouchImageView)findViewById(R.id.YOUR_TOUCH_IMAGE_VIEW_)ID);
    
        Bitmap bImage = BitmapFactory.decodeResource(this.getResources(), R.drawable.DRAWABLE_ID);
    
        touch.setImageBitmap(bImage);
    
        touch.setMaxZoom(4f); //change the max level of zoom, default is 3f
    
    
        zoonIn.setOnClickListener(new OnClickListener() {
    
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                touch.zoomIn();
            }
        });
    
    
        zoonOut.setOnClickListener(new OnClickListener() {
    
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                touch.zoomOut();
            }
        });
    
    }
    

    我希望这会有所帮助。

    【讨论】:

    • 你能帮我吗?我想修复页眉和页脚,而我需要在滚动视图中放置“ImageView”我已经这样做了,但有时我的 imageview 太短并且页脚消失了
    • 这是我的 xml,你可以编辑它以便更清楚地显示图像,但页眉和页脚应该固定
    • 这里touch的imageView尺寸非常小,出现在中间
    • @MrSMAK 可以请你帮我写相同的放大和缩小按钮的代码用于分页。我正在使用分页,在每个页面上都会有一个图像和放大和缩小按钮。哪里会我为放大和缩小按钮编写代码可能我需要在此方法中编写放大和缩小 btns 功能: public Object instantiateItem(ViewGroup container, int position) {}
    • @ErumHannan 这个链接准确地解释了你在寻找什么:androidtutorialpoints.blogspot.com/2013/10/…
    【解决方案3】:

    在按钮上放大/缩小图像最简单的方法是将其显示在 webView 中,然后您可以使用 webView 提供的所有功能。

    将图片复制到 assets 文件夹中,然后在 onCreate 中加载:

    WebView mWebView = (WebView) findViewById(R.id.webView1);
    mWebView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
    mWebView.setBackgroundColor(Color.parseColor("#ffffff"));
    mWebView.loadUrl("file:///android_asset/image.png");
    mWebView.getSettings().setBuiltInZoomControls(true);
    mWebView.setInitialScale(50);
    

    【讨论】:

    • 我怎样才能最大和最小缩放级别>
    • 通过使用 webView 支持的内置 (-/+) 缩放控制器。这是一个例子:link。或者如果你想设置初始缩放级别,使用方法:mWebView.setInitialScale(50);输入值介于 0 - 100 (%) 之间。
    • 它确实有效,所以我正在投票,但请注意与在 ImageView 中显示图像的一些区别:1) ImageView 中的图像自动调整大小以适应视图的大小,2) 有使图像在 ImageView 中居中的简单选项。
    猜你喜欢
    • 2018-05-18
    • 2013-12-11
    • 2011-06-29
    • 2021-11-22
    • 2015-11-28
    • 2017-05-11
    • 2020-07-30
    • 2014-06-21
    • 1970-01-01
    相关资源
    最近更新 更多