• Android 移动缩放的ImageView


      今天介绍一下Android中怎么实现ImageView的缩放和移动,自定义TouchImageView。

      1 public class TouchImageView extends ImageView {
      2 
      3     Matrix matrix;
      4 
      5     // We can be in one of these 3 states
      6     static final int NONE = 0;
      7     static final int DRAG = 1;
      8     static final int ZOOM = 2;
      9     int mode = NONE;
     10 
     11     // Remember some things for zooming
     12     PointF last = new PointF();
     13     PointF start = new PointF();
     14     float minScale = 1f;
     15     float maxScale = 3f;
     16     float[] m;
     17 
     18 
     19     int viewWidth, viewHeight;
     20     static final int CLICK = 3;
     21     float saveScale = 1f;
     22     protected float origWidth, origHeight;
     23     int oldMeasuredWidth, oldMeasuredHeight;
     24 
     25 
     26     ScaleGestureDetector mScaleDetector;
     27 
     28     Context context;
     29 
     30     public TouchImageView(Context context) {
     31         super(context);
     32         sharedConstructing(context);
     33     }
     34 
     35     public TouchImageView(Context context, AttributeSet attrs) {
     36         super(context, attrs);
     37         sharedConstructing(context);
     38     }
     39     
     40     private void sharedConstructing(Context context) {
     41         super.setClickable(true);
     42         this.context = context;
     43         mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
     44         matrix = new Matrix();
     45         m = new float[9];
     46         setImageMatrix(matrix);
     47         setScaleType(ScaleType.MATRIX);
     48 
     49         setOnTouchListener(new OnTouchListener() {
     50 
     51             @Override
     52             public boolean onTouch(View v, MotionEvent event) {
     53                 mScaleDetector.onTouchEvent(event);
     54                 PointF curr = new PointF(event.getX(), event.getY());
     55 
     56                 switch (event.getAction()) {
     57                     case MotionEvent.ACTION_DOWN:
     58                         last.set(curr);
     59                         start.set(last);
     60                         mode = DRAG;
     61                         break;
     62                         
     63                     case MotionEvent.ACTION_MOVE:
     64                         if (mode == DRAG) {
     65                             float deltaX = curr.x - last.x;
     66                             float deltaY = curr.y - last.y;
     67                             float fixTransX = getFixDragTrans(deltaX, viewWidth, origWidth * saveScale);
     68                             float fixTransY = getFixDragTrans(deltaY, viewHeight, origHeight * saveScale);
     69                             matrix.postTranslate(fixTransX, fixTransY);
     70                             fixTrans();
     71                             last.set(curr.x, curr.y);
     72                         }
     73                         break;
     74 
     75                     case MotionEvent.ACTION_UP:
     76                         mode = NONE;
     77                         int xDiff = (int) Math.abs(curr.x - start.x);
     78                         int yDiff = (int) Math.abs(curr.y - start.y);
     79                         if (xDiff < CLICK && yDiff < CLICK)
     80                             performClick();
     81                         break;
     82 
     83                     case MotionEvent.ACTION_POINTER_UP:
     84                         mode = NONE;
     85                         break;
     86                 }
     87                 
     88                 setImageMatrix(matrix);
     89                 invalidate();
     90                 return true; // indicate event was handled
     91             }
     92 
     93         });
     94     }
     95 
     96     public void setMaxZoom(float x) {
     97         maxScale = x;
     98     }
     99 
    100     private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
    101         @Override
    102         public boolean onScaleBegin(ScaleGestureDetector detector) {
    103             mode = ZOOM;
    104             return true;
    105         }
    106 
    107         @Override
    108         public boolean onScale(ScaleGestureDetector detector) {
    109             float mScaleFactor = detector.getScaleFactor();
    110             float origScale = saveScale;
    111             saveScale *= mScaleFactor;
    112             if (saveScale > maxScale) {
    113                 saveScale = maxScale;
    114                 mScaleFactor = maxScale / origScale;
    115             } else if (saveScale < minScale) {
    116                 saveScale = minScale;
    117                 mScaleFactor = minScale / origScale;
    118             }
    119 
    120             if (origWidth * saveScale <= viewWidth || origHeight * saveScale <= viewHeight)
    121                 matrix.postScale(mScaleFactor, mScaleFactor, viewWidth / 2, viewHeight / 2);
    122             else
    123                 matrix.postScale(mScaleFactor, mScaleFactor, detector.getFocusX(), detector.getFocusY());
    124 
    125             fixTrans();
    126             return true;
    127         }
    128     }
    129 
    130     void fixTrans() {
    131         matrix.getValues(m);
    132         float transX = m[Matrix.MTRANS_X];
    133         float transY = m[Matrix.MTRANS_Y];
    134         
    135         float fixTransX = getFixTrans(transX, viewWidth, origWidth * saveScale);
    136         float fixTransY = getFixTrans(transY, viewHeight, origHeight * saveScale);
    137 
    138         if (fixTransX != 0 || fixTransY != 0)
    139             matrix.postTranslate(fixTransX, fixTransY);
    140     }
    141 
    142     float getFixTrans(float trans, float viewSize, float contentSize) {
    143         float minTrans, maxTrans;
    144 
    145         if (contentSize <= viewSize) {
    146             minTrans = 0;
    147             maxTrans = viewSize - contentSize;
    148         } else {
    149             minTrans = viewSize - contentSize;
    150             maxTrans = 0;
    151         }
    152 
    153         if (trans < minTrans)
    154             return -trans + minTrans;
    155         if (trans > maxTrans)
    156             return -trans + maxTrans;
    157         return 0;
    158     }
    159     
    160     float getFixDragTrans(float delta, float viewSize, float contentSize) {
    161         if (contentSize <= viewSize) {
    162             return 0;
    163         }
    164         return delta;
    165     }
    166 
    167     @Override
    168     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    169         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    170         viewWidth = MeasureSpec.getSize(widthMeasureSpec);
    171         viewHeight = MeasureSpec.getSize(heightMeasureSpec);
    172         
    173         //
    174         // Rescales image on rotation
    175         //
    176         if (oldMeasuredHeight == viewWidth && oldMeasuredHeight == viewHeight
    177                 || viewWidth == 0 || viewHeight == 0)
    178             return;
    179         oldMeasuredHeight = viewHeight;
    180         oldMeasuredWidth = viewWidth;
    181 
    182         if (saveScale == 1) {
    183             //Fit to screen.
    184             float scale;
    185 
    186             Drawable drawable = getDrawable();
    187             if (drawable == null || drawable.getIntrinsicWidth() == 0 || drawable.getIntrinsicHeight() == 0)
    188                 return;
    189             int bmWidth = drawable.getIntrinsicWidth();
    190             int bmHeight = drawable.getIntrinsicHeight();
    191             
    192             Log.d("bmSize", "bmWidth: " + bmWidth + " bmHeight : " + bmHeight);
    193 
    194             float scaleX = (float) viewWidth / (float) bmWidth;
    195             float scaleY = (float) viewHeight / (float) bmHeight;
    196             scale = Math.min(scaleX, scaleY);
    197             matrix.setScale(scale, scale);
    198 
    199             // Center the image
    200             float redundantYSpace = (float) viewHeight - (scale * (float) bmHeight);
    201             float redundantXSpace = (float) viewWidth - (scale * (float) bmWidth);
    202             redundantYSpace /= (float) 2;
    203             redundantXSpace /= (float) 2;
    204 
    205             matrix.postTranslate(redundantXSpace, redundantYSpace);
    206 
    207             origWidth = viewWidth - 2 * redundantXSpace;
    208             origHeight = viewHeight - 2 * redundantYSpace;
    209             setImageMatrix(matrix);
    210         }
    211         fixTrans();
    212     }
    213 }
  • 相关阅读:
    C++ 顺序表实现
    C++ 第三十四天
    C++ 第三十三天
    机器学习相关- 学习资料收集
    【Debian 8.8】Java 8 安装以及环境变量配置
    算法导论(第三版)练习 1.2-1 ~ 1.1-3
    条款33: 明智地使用内联
    条款32: 尽可能地推迟变量的定义
    条款31: 千万不要返回局部对象的引用,也不要返回函数内部用new初始化的指针的引用
    【Nginx】进程模型
  • 原文地址:https://www.cnblogs.com/phj981805903/p/3239687.html
Copyright © 2020-2023  润新知