自定义ImageView实现拖动、旋转、缩放功能

来源:互联网 发布:video.js flash 编辑:程序博客网 时间:2024/05/16 02:14

直接上自定义Imageview代码

import android.app.Activity;import android.content.Context;import android.graphics.Bitmap;import android.graphics.Matrix;import android.graphics.PointF;import android.util.AttributeSet;import android.util.FloatMath;import android.view.MotionEvent;import android.widget.ImageView;public class MultiTouchImageView extends ImageView {    private float startDis;    private PointF midPoint;    private float oldRotation = 0;    private float rotation = 0;    private PointF startPoint = new PointF();    private Matrix matrix = new Matrix();    private Matrix currentMatrix = new Matrix();    private Activity mActivity;    private boolean is_Editable = true;    public int width;    public int height;    float matrixX, matrixY;    float saveScale = 1f;    float minScale = 1f;    float maxScale = 3f;    float redundantXSpace, redundantYSpace;    float right, bottom, origWidth, origHeight, bmWidth, bmHeight;    float[] m;    private enum MODE {        NONE, DRAG, ZOOM    };    private MODE mode = MODE.NONE;// 默认模式    public MultiTouchImageView(Context context) {        super(context);    }    public void setmActivity(Activity mActivity) {        this.mActivity = mActivity;    }    public void setis_Editable(boolean is_Editable) {        this.is_Editable = is_Editable;    }    public boolean getis_Editable() {        return this.is_Editable;    }    public MultiTouchImageView(Context context, AttributeSet attrs) {        super(context, attrs);    }    public static float distance(MotionEvent event) {        float dx = event.getX(1) - event.getX(0);        float dy = event.getY(1) - event.getY(0);        return FloatMath.sqrt(dx * dx + dy * dy);    }    /**     * 计算两点之间的中间点     *      * @param event     * @return     */    public static PointF mid(MotionEvent event) {        float midX = (event.getX(1) + event.getX(0)) / 2;        float midY = (event.getY(1) + event.getY(0)) / 2;        return new PointF(midX, midY);    }    private float rotation(MotionEvent event) {        double delta_x = (event.getX(0) - event.getX(1));        double delta_y = (event.getY(0) - event.getY(1));        double radians = Math.atan2(delta_y, delta_x);        return (float) Math.toDegrees(radians);    }    /***     * touch 事件     */    private int lastX, lastY;    @Override    public boolean onTouchEvent(MotionEvent event) {        /** 处理单点、多点触控 **/        if (is_Editable == true) {            switch (event.getAction() & MotionEvent.ACTION_MASK) {            case MotionEvent.ACTION_DOWN:// 手指压下屏幕                mode = MODE.DRAG;                currentMatrix.set(this.getImageMatrix());// 记录ImageView当前的移动位�?                matrix.set(currentMatrix);                startPoint.set(event.getX(), event.getY());                postInvalidate();                lastX = (int) event.getRawX();                lastY = (int) event.getRawY();                break;            case MotionEvent.ACTION_POINTER_DOWN:// 当屏幕上还有触点(手指),再有一个手指压下屏�?                mode = MODE.ZOOM;                oldRotation = rotation(event);                startDis = distance(event);                if (startDis > 10f) {                    midPoint = mid(event);                    currentMatrix.set(this.getImageMatrix());// 记录ImageView当前的缩放�?�数                }                break;            case MotionEvent.ACTION_MOVE:// 手指在屏幕移动,�? 事件会不断地触发                if (mode == MODE.DRAG) {                    float dx = event.getX() - startPoint.x;// 得到在x轴的移动距离                    float dy = event.getY() - startPoint.y;// 得到在y轴的移动距离                    matrix.set(currentMatrix);// 在没有进行移动之前的位置基础上进行移�?                    matrix.postTranslate(dx, dy);                } else if (mode == MODE.ZOOM) {// 缩放与旋�?                    float endDis = distance(event);// 结束距离                    rotation = (rotation(event) - oldRotation);                    if (endDis > 10f) {                        float scale = endDis / startDis;// 得到缩放倍数                        matrix.set(currentMatrix);                        matrix.postScale(scale, scale, midPoint.x, midPoint.y);                        matrix.postRotate(rotation, midPoint.x, midPoint.y);                    }                }                break;            case MotionEvent.ACTION_UP:// 手指离开�?                // 设置不能出界                int dx = (int) event.getRawX() - lastX;                int dy = (int) event.getRawY() - lastY;                int left = this.getLeft() + dx;                int top = this.getTop() + dy;                int right = this.getRight() + dx;                if (left < 0) {                    left = 0;                    right = left + this.getWidth();                }                if (right > width) {                    right = (int) width;                    left = right - this.getWidth();                }                break;            case MotionEvent.ACTION_POINTER_UP:// 有手指离�?屏幕,但屏幕还有触点(手指�?                mode = MODE.NONE;                break;            }            this.setImageMatrix(matrix);        }        return true;    }    private void calcPadding() {        right = width * saveScale - width - (2 * redundantXSpace * saveScale);        bottom = height * saveScale - height - (2 * redundantYSpace * saveScale);    }    private void fillMatrixXY() {        matrix.getValues(m);        matrixX = m[Matrix.MTRANS_X];        matrixY = m[Matrix.MTRANS_Y];    }    private void scaleMatrixToBounds() {        if (Math.abs(matrixX + right / 2) > 0.5f)            matrix.postTranslate(-(matrixX + right / 2), 0);        if (Math.abs(matrixY + bottom / 2) > 0.5f)            matrix.postTranslate(0, -(matrixY + bottom / 2));    }    public Bitmap getImageBitmap() {        // ImageView对象必须做如下设置后,才能获取其中的图像        setDrawingCacheEnabled(true);        // 获取ImageView中的图像        Bitmap obmp = Bitmap.createBitmap(getDrawingCache());        // 从ImaggeView对象中获取图像后,要记得调用setDrawingCacheEnabled(false)清空画图�?        // 冲区,否则,下一次用getDrawingCache()方法回去图像时,还是原来的图�?        setDrawingCacheEnabled(false);        return obmp;    }}

布局中写入

<com.example.mulimageview.MultiTouchImageView        android:id="@+id/imageveiw"        android:layout_width="fill_parent"        android:layout_height="fill_parent"        android:layout_gravity="center_horizontal"        android:paddingLeft="100dp"        android:paddingTop="100dp"        <-- 缩放规则要使用matrix -->        android:scaleType="matrix" />

使用,其实就一句代码的事

import android.app.Activity;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Bundle;public class MainActivity extends Activity {    private MultiTouchImageView imageview;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        imageview = (MultiTouchImageView) findViewById(R.id.imageveiw);        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.male_show_122x124);        //使用其实就这一句代码,简单吧        imageview.setImageBitmap(bitmap);    }}

惯例,附上demo地址:http://download.csdn.net/detail/qq_30124547/9575319

0 0
原创粉丝点击