• android 双击图片变大,缩放功能


    package com.example.administrator.myapplicationphotochange;
    
    /**
     * Created by Administrator on 2016/8/22.
     */
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.Matrix;
    import android.util.AttributeSet;
    import android.util.FloatMath;
    import android.view.MotionEvent;
    import android.widget.ImageView;
    
    public class ImageControl extends ImageView {
        public ImageControl(Context context) {
            super(context);
            // TODO Auto-generated constructor stub
        }
    
        public ImageControl(Context context, AttributeSet attrs) {
            super(context, attrs);
            // TODO Auto-generated constructor stub
        }
    
        public ImageControl(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            // TODO Auto-generated constructor stub
        }
    
        // ImageView img;
        Matrix imgMatrix = null; // 定义图片的变换矩阵
    
        static final int DOUBLE_CLICK_TIME_SPACE = 300; // 双击时间间隔
        static final int DOUBLE_POINT_DISTANCE = 10; // 两点放大两点间最小间距
        static final int NONE = 0;
        static final int DRAG = 1; // 拖动操作
        static final int ZOOM = 2; // 放大缩小操作
        private int mode = NONE; // 当前模式
    
        float bigScale = 3f; // 默认放大倍数
        Boolean isBig = false; // 是否是放大状态
        long lastClickTime = 0; // 单击时间
        float startDistance; // 多点触摸两点距离
        float endDistance; // 多点触摸两点距离
    
        float topHeight; // 状态栏高度和标题栏高度
        Bitmap primaryBitmap = null;
    
        float contentW; // 屏幕内容区宽度
        float contentH; // 屏幕内容区高度
    
        float primaryW; // 原图宽度
        float primaryH; // 原图高度
    
        float scale; // 适合屏幕缩放倍数
        Boolean isMoveX = true; // 是否允许在X轴拖动
        Boolean isMoveY = true; // 是否允许在Y轴拖动
        float startX;
        float startY;
        float endX;
        float endY;
        float subX;
        float subY;
        float limitX1;
        float limitX2;
        float limitY1;
        float limitY2;
        ICustomMethod mCustomMethod = null;
    
        /**
         * 初始化图片
         *
         * @param bitmap
         *            要显示的图片
         * @param contentW
         *            内容区域宽度
         * @param contentH
         *            内容区域高度
         * @param topHeight
         *            状态栏高度和标题栏高度之和
         */
        public void imageInit(Bitmap bitmap, int contentW, int contentH,
                              int topHeight, ICustomMethod iCustomMethod) {
            this.primaryBitmap = bitmap;
            this.contentW = contentW;
            this.contentH = contentH;
            this.topHeight = topHeight;
            mCustomMethod = iCustomMethod;
            primaryW = primaryBitmap.getWidth();
            primaryH = primaryBitmap.getHeight();
            float scaleX = (float) contentW / primaryW;
            float scaleY = (float) contentH / primaryH;
            scale = scaleX < scaleY ? scaleX : scaleY;
            if (scale < 1 && 1 / scale < bigScale) {
                bigScale = (float) (1 / scale + 0.5);
            }
    
            imgMatrix = new Matrix();
            subX = (contentW - primaryW * scale) / 2;
            subY = (contentH - primaryH * scale) / 2;
            this.setImageBitmap(primaryBitmap);
            this.setScaleType(ScaleType.MATRIX);
            imgMatrix.postScale(scale, scale);
            imgMatrix.postTranslate(subX, subY);
            this.setImageMatrix(imgMatrix);
        }
    
        /**
         * 按下操作
         *
         * @param event
         */
        public void mouseDown(MotionEvent event) {
            mode = NONE;
            startX = event.getRawX();
            startY = event.getRawY();
            if (event.getPointerCount() == 1) {
                // 如果两次点击时间间隔小于一定值,则默认为双击事件
                if (event.getEventTime() - lastClickTime < DOUBLE_CLICK_TIME_SPACE) {
                    changeSize(startX, startY);
                } else if (isBig) {
                    mode = DRAG;
                }
            }
    
            lastClickTime = event.getEventTime();
        }
    
        /**
         * 非第一个点按下操作
         *
         * @param event
         */
        public void mousePointDown(MotionEvent event) {
            startDistance = getDistance(event);
            if (startDistance > DOUBLE_POINT_DISTANCE) {
                mode = ZOOM;
            } else {
                mode = NONE;
            }
        }
    
        /**
         * 移动操作
         *
         * @param event
         */
        public void mouseMove(MotionEvent event) {
            if ((mode == DRAG) && (isMoveX || isMoveY)) {
                float[] XY = getTranslateXY(imgMatrix);
                float transX = 0;
                float transY = 0;
                if (isMoveX) {
                    endX = event.getRawX();
                    transX = endX - startX;
                    if ((XY[0] + transX) <= limitX1) {
                        transX = limitX1 - XY[0];
                    }
                    if ((XY[0] + transX) >= limitX2) {
                        transX = limitX2 - XY[0];
                    }
                }
                if (isMoveY) {
                    endY = event.getRawY();
                    transY = endY - startY;
                    if ((XY[1] + transY) <= limitY1) {
                        transY = limitY1 - XY[1];
                    }
                    if ((XY[1] + transY) >= limitY2) {
                        transY = limitY2 - XY[1];
                    }
                }
    
                imgMatrix.postTranslate(transX, transY);
                startX = endX;
                startY = endY;
                this.setImageMatrix(imgMatrix);
            } else if (mode == ZOOM && event.getPointerCount() > 1) {
                endDistance = getDistance(event);
                float dif = endDistance - startDistance;
                if (Math.abs(endDistance - startDistance) > DOUBLE_POINT_DISTANCE) {
                    if (isBig) {
                        if (dif < 0) {
                            changeSize(0, 0);
                            mode = NONE;
                        }
                    } else if (dif > 0) {
                        float x = event.getX(0) / 2 + event.getX(1) / 2;
                        float y = event.getY(0) / 2 + event.getY(1) / 2;
                        changeSize(x, y);
                        mode = NONE;
                    }
                }
            }
        }
    
        /**
         * 鼠标抬起事件
         */
        public void mouseUp() {
            mode = NONE;
        }
    
        /**
         * 图片放大缩小
         *
         * @param x
         *            点击点X坐标
         * @param y
         *            点击点Y坐标
         */
        private void changeSize(float x, float y) {
            if (isBig) {
                // 如果处于最大状态,则还原
                imgMatrix.reset();
                imgMatrix.postScale(scale, scale);
                imgMatrix.postTranslate(subX, subY);
                isBig = false;
            } else {
                imgMatrix.postScale(bigScale, bigScale); // 在原有矩阵后乘放大倍数
                float transX = -((bigScale - 1) * x);
                float transY = -((bigScale - 1) * (y - topHeight)); // (bigScale-1)(y-statusBarHeight-subY)+2*subY;
                float currentWidth = primaryW * scale * bigScale; // 放大后图片大小
                float currentHeight = primaryH * scale * bigScale;
                // 如果图片放大后超出屏幕范围处理
                if (currentHeight > contentH) {
                    limitY1 = -(currentHeight - contentH); // 平移限制
                    limitY2 = 0;
                    isMoveY = true; // 允许在Y轴上拖动
                    float currentSubY = bigScale * subY; // 当前平移距离
                    // 平移后,内容区域上部有空白处理办法
                    if (-transY < currentSubY) {
                        transY = -currentSubY;
                    }
                    // 平移后,内容区域下部有空白处理办法
                    if (currentSubY + transY < limitY1) {
                        transY = -(currentHeight + currentSubY - contentH);
                    }
                } else {
                    // 如果图片放大后没有超出屏幕范围处理,则不允许拖动
                    isMoveY = false;
                }
    
                if (currentWidth > contentW) {
                    limitX1 = -(currentWidth - contentW);
                    limitX2 = 0;
                    isMoveX = true;
                    float currentSubX = bigScale * subX;
                    if (-transX < currentSubX) {
                        transX = -currentSubX;
                    }
                    if (currentSubX + transX < limitX1) {
                        transX = -(currentWidth + currentSubX - contentW);
                    }
                } else {
                    isMoveX = false;
                }
    
                imgMatrix.postTranslate(transX, transY);
                isBig = true;
            }
    
            this.setImageMatrix(imgMatrix);
            if (mCustomMethod != null) {
                mCustomMethod.customMethod(isBig);
            }
        }
    
        /**
         * 获取变换矩阵中X轴偏移量和Y轴偏移量
         *
         * @param matrix
         *            变换矩阵
         * @return
         */
        private float[] getTranslateXY(Matrix matrix) {
            float[] values = new float[9];
            matrix.getValues(values);
            float[] floats = new float[2];
            floats[0] = values[Matrix.MTRANS_X];
            floats[1] = values[Matrix.MTRANS_Y];
            return floats;
        }
    
        /**
         * 获取两点间的距离
         *
         * @param event
         * @return
         */
        private float getDistance(MotionEvent event) {
            float x = event.getX(0) - event.getX(1);
            float y = event.getY(0) - event.getY(1);
            return(float)Math.sqrt(x * x + y * y);
        }
    
        /**
         * @author Administrator 用户自定义方法
         */
        public interface ICustomMethod {
            public void customMethod(Boolean currentStatus);
        }
    }
    View Code
    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context="com.example.administrator.myapplicationphotochange.MainActivity">
    
    
        <com.example.administrator.myapplicationphotochange.ImageControl
            android:id="@+id/common_imageview_imageControl1"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:src="@mipmap/ic_launcher" />
    
        <LinearLayout
            android:id="@+id/common_imageview_llTitle"
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true" >
    
            <TextView
                android:id="@+id/common_imageview_title"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="报告" />
        </LinearLayout>
    
    </RelativeLayout>
    View Code
    package com.example.administrator.myapplicationphotochange;
    
    import android.graphics.Bitmap;
    import android.graphics.Rect;
    import android.graphics.drawable.BitmapDrawable;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.MotionEvent;
    import android.view.View;
    import android.widget.LinearLayout;
    import android.widget.TextView;
    import android.widget.Toast;
    
    public class MainActivity extends AppCompatActivity {
    
        ImageControl imgControl;
        LinearLayout llTitle;
        TextView tvTitle;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            findView();
            tvTitle.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(MainActivity.this,"ssssssssss",Toast.LENGTH_LONG).show();
                }
            });
        }
    
        public void onWindowFocusChanged(boolean hasFocus) {
            super.onWindowFocusChanged(hasFocus);
            init();
        }
    
    
    
        private void findView() {
            imgControl = (ImageControl) findViewById(R.id.common_imageview_imageControl1);
            llTitle = (LinearLayout) findViewById(R.id.common_imageview_llTitle);
            tvTitle = (TextView) findViewById(R.id.common_imageview_title);
        }
    
        private void init() {
            tvTitle.setText("图片测试");
            // 这里可以为imgcontrol的图片路径动态赋值
            // ............
    
            Bitmap bmp;
            if (imgControl.getDrawingCache() != null) {
                bmp = Bitmap.createBitmap(imgControl.getDrawingCache());
            } else {
                bmp = ((BitmapDrawable) imgControl.getDrawable()).getBitmap();
            }
            Rect frame = new Rect();
            getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
            int statusBarHeight = frame.top;
            int screenW = this.getWindowManager().getDefaultDisplay().getWidth();
            int screenH = this.getWindowManager().getDefaultDisplay().getHeight()
                    - statusBarHeight;
            if (bmp != null) {
                imgControl.imageInit(bmp, screenW, screenH, statusBarHeight,
                        new ImageControl.ICustomMethod() {
    
                            @Override
                            public void customMethod(Boolean currentStatus) {
                                // 当图片处于放大或缩小状态时,控制标题是否显示
                                if (currentStatus) {
                                    llTitle.setVisibility(View.GONE);
                                } else {
                                    llTitle.setVisibility(View.VISIBLE);
                                }
                            }
                        });
            }
            else
            {
                Toast.makeText(MainActivity.this, "图片加载失败,请稍候再试!", Toast.LENGTH_SHORT)
                        .show();
            }
    
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            switch (event.getAction() & MotionEvent.ACTION_MASK) {
                case MotionEvent.ACTION_DOWN:
                    imgControl.mouseDown(event);
                    break;
    
                /**
                 * 非第一个点按下
                 */
                case MotionEvent.ACTION_POINTER_DOWN:
    
                    imgControl.mousePointDown(event);
    
                    break;
                case MotionEvent.ACTION_MOVE:
                    imgControl.mouseMove(event);
    
                    break;
    
                case MotionEvent.ACTION_UP:
                    imgControl.mouseUp();
                    break;
    
            }
    
            return super.onTouchEvent(event);
        }
    }
    View Code
    今天多一点积累,明天少一分烦恼
  • 相关阅读:
    最大子数组问题
    剑指offer python版 树的子结构
    剑指offer python版 重建二叉树
    剑指offer python版 字符串变成整数
    剑指offer python版 构建乘积数组
    剑指offer python版 不用加减乘除做加法
    剑指offer python版 求1+2+…+n
    剑指offer python版 股票最大收益
    剑指offer python版 圆圈中最后剩下的数字
    剑指offer python版 扑克牌的顺子
  • 原文地址:https://www.cnblogs.com/galibujianbusana/p/5798034.html
Copyright © 2020-2023  润新知