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事件有冲突,需要做下处理。