android自定义相片滑动imageview组件
android自定义照片滑动imageview组件
项目有照片游览添加需求,照片加载之后,能上下左右滑动,点击操作为添加照片
初始化界面
添加照片之后界面
主要代码:
自定义的Imageview
import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.MotionEvent; import android.widget.ImageView; /** */ public class AlbumCropView extends ImageView { /** * the transformation matrix of drawable */ private Matrix mMatrix = new Matrix(); /** * the scaling of intrinsic drawable */ private float mScale; /** * the x translate of top left */ private float mTranslateX = 0; /** * the y translate of top left */ private float mTranslateY = 0; /** * the last motion x coordinate */ private float lastX; /** * the last motion y coordinate */ private float lastY; /** * can translate on x coordinate */ private boolean canTranslateX; /** * can translate on y coordinate */ private boolean canTranslateY; /** * the width of drawable */ private int viewWidth; /** * the height of drawable */ private int viewHeight; /** * the scale width of intrinsic drawable */ private float afterScaleWidth; /** * the scale height of intrinsic drawable */ private float afterScaleHeight; /** * 当前触摸点相对于屏幕的坐标 */ private int mCurrentInScreenX; private int mCurrentInScreenY; /** * 触摸点按下时的相对于屏幕的坐标 */ private int mDownInScreenX; private int mDownInScreenY; private boolean supportMoveAble = true; public AlbumCropView(Context context) { super(context); init(); } public AlbumCropView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public AlbumCropView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { setScaleType(ScaleType.FIT_CENTER); supportMoveAble = false; } @Override public void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); createBasedAlbumCropView(); } @Override public void onDraw(Canvas canvas) { super.onDraw(canvas); } @Override public boolean setFrame(int left, int top, int right, int bottom) { return super.setFrame(left, top, right, bottom); } /* * (non-Javadoc) * * @see android.view.View#onTouchEvent(android.view.MotionEvent) */ @Override public boolean onTouchEvent(MotionEvent event) { if (!isSupportMoveAble()) { return super.onTouchEvent(event); } moveWithFinger(event); if (isMoved()) { return true; } else { return super.onTouchEvent(event); } } /** * 判断是否移动 * * @return */ private boolean isMoved() { // 允许有5的偏差 在判断是否移动的时候 if (Math.abs(mDownInScreenX - mCurrentInScreenX) <= 5 && Math.abs(mDownInScreenY - mCurrentInScreenY) <= 5) { return false; } else { return true; } } /** * get scale factor * * @return */ public float getScale() { return this.mScale; } /** * get top left crop x coordinate * * @return */ public float getTranslateX() { return this.mTranslateX; } /** * get top left crop y coordinate * * @return */ public float getTranslateY() { return this.mTranslateY; } /** * get scale image width * * @return */ public int getViewWidth() { return this.viewWidth; } /** * get scale image height * * @return */ public int getViewHeight() { return this.viewHeight; } private void moveWithFinger(MotionEvent event) { // 获取相对屏幕的坐标,即以屏幕左上角为原点 mCurrentInScreenX = (int) event.getRawX(); mCurrentInScreenY = (int) event.getRawY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: lastX = event.getX(); lastY = event.getY(); mDownInScreenX = (int) event.getRawX(); mDownInScreenY = (int) event.getRawY(); break; case MotionEvent.ACTION_UP: // 记录Down下时的坐标 break; case MotionEvent.ACTION_MOVE: if (canTranslateX) { float currentMotionX = event.getX(); float motionX = currentMotionX - lastX; if (this.mTranslateX - motionX > this.afterScaleWidth - this.getWidth()) { this.mTranslateX = this.afterScaleWidth - this.getWidth(); } else if (this.mTranslateX - motionX < 0) { this.mTranslateX = 0; } else { this.mTranslateX -= motionX; } lastX = currentMotionX; this.mTranslateY = 0; } else if (canTranslateY) { float currentMotionY = event.getY(); float motionY = currentMotionY - lastY; if (this.mTranslateY - motionY > this.afterScaleHeight - this.getHeight()) { this.mTranslateY = this.afterScaleHeight - this.getHeight(); } else if (this.mTranslateY - motionY < 0) { this.mTranslateY = 0; } else { this.mTranslateY -= motionY; } lastY = currentMotionY; this.mTranslateX = 0; } else { this.mTranslateX = 0; this.mTranslateY = 0; } break; } mMatrix.reset(); mMatrix.setScale(this.mScale, this.mScale); mMatrix.postTranslate(-this.mTranslateX, -this.mTranslateY); this.setImageMatrix(mMatrix); } public void setmTranslate(float mTranslateX, float mTranslateY) { this.mTranslateX = mTranslateX; this.mTranslateY = mTranslateY; } @Override public void setImageBitmap(Bitmap bm) { super.setImageBitmap(bm); supportMoveAble = true; } @Override public void setImageResource(int resId) { super.setImageResource(resId); if (resId == R.drawable.image_photo_album_add) { setScaleType(ScaleType.FIT_CENTER); supportMoveAble = false; } } private void createBasedAlbumCropView() { if (!isSupportMoveAble()) { return; } Drawable mDrawable = getDrawable(); this.setPadding(0, 0, 0, 0); viewWidth = this.getWidth(); viewHeight = this.getHeight(); if (mDrawable == null) { return; } this.setImageDrawable(mDrawable); final int drawableWidth = mDrawable.getIntrinsicWidth(); final int drawableHeight = mDrawable.getIntrinsicHeight(); float scaleX = viewWidth / (float) drawableWidth; float scaleY = viewHeight / (float) drawableHeight; if (scaleX > scaleY) { this.mScale = scaleX; this.canTranslateX = false; this.canTranslateY = true; } else if (scaleX < scaleY) { this.mScale = scaleY; this.canTranslateX = true; this.canTranslateY = false; } else { this.mScale = scaleX; this.canTranslateX = false; this.canTranslateY = false; } this.afterScaleWidth = drawableWidth * this.mScale; this.afterScaleHeight = drawableHeight * this.mScale; this.setScaleType(ScaleType.MATRIX); mMatrix.reset(); mMatrix.setScale(this.mScale, this.mScale); mMatrix.postTranslate(-this.mTranslateX, -this.mTranslateY); this.setImageMatrix(mMatrix); } public float getmTranslateX() { return mTranslateX; } public float getmTranslateY() { return mTranslateY; } public boolean isSupportMoveAble() { return supportMoveAble; } public void setSupportMoveAble(boolean supportMoveAble) { this.supportMoveAble = supportMoveAble; } }
该自定义组件支持2图照片的滑动效果,点击事件为添加操作,因为onTouchEvent和onclick事件有冲突,需要做下处理。