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

猜你喜欢

转载自zhousheng193.iteye.com/blog/2245351