可移动的ImageView

 

 

今天做了一个可移动的ImageView,要点如下:

1 ontouch

2 ongloballayout

3 image放置适当的位置

4 matrix变换(平移,缩放)

代码很简单

activity_main.xml

              

MainActivity.java

package com.none.moveimage;    import android.support.v7.app.ActionBarActivity;  import android.os.Bundle;  import android.view.Menu;  import android.view.MenuItem;  import android.widget.ImageView;    import com.none.view.MoveImage;      public class MainActivity extends ActionBarActivity {        @Override      protected void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.activity_main);            MoveImage img = (MoveImage)findViewById(R.id.id_img);          img.setImageResource(R.drawable.dou);      }  }  

MoveImage.java

package com.none.view;    import android.content.Context;  import android.graphics.Matrix;  import android.graphics.RectF;  import android.graphics.drawable.Drawable;  import android.util.AttributeSet;  import android.view.MotionEvent;  import android.view.View;  import android.view.ViewConfiguration;  import android.view.ViewTreeObserver;  import android.widget.ImageView;    /**  * Created by pc on 2015/5/11.  */  public class MoveImage extends ImageView implements ViewTreeObserver.OnGlobalLayoutListener, View.OnTouchListener {        private boolean mInit;      private boolean mIsCanMove;      private float mLastX;      private float mLastY;      private Matrix mScaleMatrix;      private int mMoveSlop;        public MoveImage(Context context) {          this(context, null);      }        public MoveImage(Context context, AttributeSet attrs) {          this(context, attrs, 0);      }        public MoveImage(Context context, AttributeSet attrs, int defStyleAttr) {          super(context, attrs, defStyleAttr);            init(context);      }        private void init(Context context) {          mScaleMatrix = new Matrix();          mMoveSlop = ViewConfiguration.get(context).getScaledTouchSlop();          setOnTouchListener(this);          mIsCanMove = false;      }        @Override      protected void onAttachedToWindow() {          getViewTreeObserver().addOnGlobalLayoutListener(this);      }        @Override      protected void onDetachedFromWindow() {          getViewTreeObserver().removeOnGlobalLayoutListener(this);      }        @Override      public void onGlobalLayout() {          if (!mInit) {              Drawable d = getDrawable();              if (d != null) {                  float scale = 1.0f;                    int dw = d.getIntrinsicWidth();                  int dh = d.getIntrinsicHeight();                    int width = getWidth();                  int height = getHeight();                    if (dw > width && dh < height) {                      scale = width * 1.0f / dw;                  } else if (dw < width && dh > height) {                      scale = height * 1.0f / dh;                  } else if (dw < width && dh < height) {                      scale = Math.min(width * 1.0f / dw, height * 1.0f / dh);                  } else if (dw > width && dh > height) {                      scale = Math.min(width * 1.0f / dw, height * 1.0f / dh);                  } else {                      scale = 1.0f;                  }                    int centerX = (width - dw) / 2;                  int centerY = (height - dh) / 2;                  mScaleMatrix.postTranslate(centerX, centerY);                  scale = scale / 2.0f;                  mScaleMatrix.postScale(scale, scale, width / 2, height / 2);                  setImageMatrix(mScaleMatrix);              }          }          mInit = true;      }        private RectF getMatrixRectF() {          RectF rectf = new RectF();          final Matrix matrix = mScaleMatrix;          Drawable d = getDrawable();          if (d != null) {              rectf.set(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());              matrix.mapRect(rectf);          }          return rectf;      }        private boolean isMoveAction(float dx, float dy) {          return Math.sqrt(dx * dx + dy * dy) > mMoveSlop;      }        @Override      public boolean onTouch(View v, MotionEvent event) {          RectF rectF = getMatrixRectF();          switch (event.getAction()) {              case MotionEvent.ACTION_DOWN:                  mLastX = event.getX();                  mLastY = event.getY();                  mIsCanMove = rectF.contains(mLastX, mLastY);                  break;              case MotionEvent.ACTION_MOVE:                  if (mIsCanMove) {                      float x = event.getX();                      float y = event.getY();                      float deltaX = x - mLastX;                      float deltaY = y - mLastY;                        if (isMoveAction(deltaX, deltaY)) {                          checkBorderWhenMove(deltaX, deltaY, rectF);                          setImageMatrix(mScaleMatrix);                      }                        mLastX = x;                      mLastY = y;                  }                  break;              case MotionEvent.ACTION_UP:              case MotionEvent.ACTION_CANCEL:                  mIsCanMove = false;                  break;          }          return true;      }        private void checkBorderWhenMove(float deltaX, float deltaY, RectF rectF) {          int width = getWidth();          int height = getHeight();            if (rectF.left + deltaX < 0) {              deltaX = -rectF.left;          } else if (rectF.right + deltaX > width) {              deltaX = width - rectF.right;          }          if (rectF.top + deltaY < 0) {              deltaY = -rectF.top;          } else if (rectF.bottom + deltaY > height) {              deltaY = height - rectF.bottom;          }          mScaleMatrix.postTranslate(deltaX, deltaY);      }  }  


其中图片缩放使用了matrix方式,在xml中需要将imageview的scale方式设置为matrix。

 

之后在根据ongloballayout中的得到的图片size和屏幕大小进行比例计算,之后使用matrix.postscale对图片进行缩放。

图片的平移使用了matrix.posttranslate,平移的距离可随意指定。

另外还需要获得每次缩放后图片的rectf,也就是图片当前的位置。这个可以使用matrix.maprect获得。

最后在ontouch中控制图片的平移,在Down中对触摸点进行判断,非图片的点击不会对图片产生影响,当点击的是图片时,使用setimagematrix对图片移动进行刷新。

在移动的过程中判断图片是否会移动出屏幕,对上下左右进行判断,防止图片移动出屏幕。

 

参考http://www.imooc.com/learn/239中对图片伸缩和伸缩和的上下左右位置的处理。


Taily老段的微信公众号,欢迎交流学习

https://blog.csdn.net/taily_duan/article/details/81214815


 

更多相关文章

  1. android 设置全屏显示 和 自适应屏幕
  2. 短视频带货源码,解决Dialog 不铺满屏幕问题
  3. android传递图片和图片与byte转换
  4. Android获取屏幕尺寸的方法
  5. Android设备系统及屏幕分辨率统计信息汇总(截至2018年7月)
  6. android 实现全屏幕
  7. android调用系统摄像头拍照图片和视频

随机推荐

  1. INSTALL_FAILED_CONFLICTING_PROVIDER 错
  2. Android Studio TV开发教程(十六)让电视应
  3. Android Service---启动服务
  4. Android核心分析(19)----电话系统之GSMCall
  5. Android实现内存中数据保存到sdcard的方
  6. 怎么查看Android编译时候交叉编译链工具
  7. android开发游记:从viewpager禁用滚动 总
  8. android adb devices 后出现offline问题
  9. Android(安卓)L 64位兼容32 应用程序的认
  10. android:通过Android命令自动编译出build.