android 動態放大縮小拖曳圖片imageView

因爲在Android中不允許ImageView在產生後,動態修改其長度與寬度,所以爲了實現圖片放大、縮小的功能,使用的方式是當用戶在單擊放大或縮小的按鈕時,除了將圖片作放大或縮小的動作外,並將原來Layout中的ImageView刪除,重新產生一個新的ImageView,指定圖片給它後,再放入Layout裏。用戶看起來,就好像是同一張圖片在放大或縮小。

在放大、縮小圖片文件時使用的Martix對象,除了可以用來作圖片的縮放外,還有非常實用的旋轉效果.下面包含兩種方法imageview.setImageBitmap和setImageMatrix,注意兩者的細小區別,前者需要再次setContentView包含imageView的父佈局,而後者則不需要,但是這只是imageView的父佈局爲佈局文件的根節點的情況。實例如下:


public class CBI_Activity extends Activity {
    private ImageView img;
    private ZoomControls zControls;
    private FrameLayout layout;
    private float zoomin = (float) 1.2;
    private float zoomout = (float) 0.8;
    private float scaleHeight = 1;
    private float scaleWdith = 1;
    private Bitmap bitmap;
    private int id = 0;//在java代碼添加控件,也需要給控件添加id,便於刪除操作
    private int displayWidth;
    private int displayHeight;
    private int height_one;
    private int width_one;
    private ImageViewTouchListener listener;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.cbimgdisplay);
        listener = new ImageViewTouchListener();
        DisplayMetrics dm = new DisplayMetrics();

        getWindowManager().getDefaultDisplay().getMetrics(dm);
        displayWidth = dm.widthPixels;
        /* 屏幕高度須扣除下方Button高度 */
        displayHeight = dm.heightPixels - 80;
        img = (ImageView) findViewById(R.id.cbidisplay);
        layout = (FrameLayout) findViewById(R.id.layout);
        Intent intent = getIntent();
        String imgName = (String) intent.getExtras().get("imgName");
        bitmap = ImgUtil.getBitmapByFilename(imgName);
        img.setImageBitmap(bitmap);
        img.setOnTouchListener(listener);
        zControls = (ZoomControls) this.findViewById(R.id.zoomControls1);
        // zControls.setEnabled(true);//
        zControls.setOnZoomInClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                Toast.makeText(CBI_Activity.this,
                        "縮小," + scaleWdith + "," + scaleHeight,
                        Toast.LENGTH_SHORT).show();
                bigImg();
            }

            private void bigImg() {
                width_one = bitmap.getWidth();
                height_one = bitmap.getHeight();
                if (width_one > displayWidth || height_one > displayHeight) {
                    Toast.makeText(CBI_Activity.this,
                            "放大已經超過了屏幕的尺寸,不能再放大" + scaleWdith,
                            Toast.LENGTH_SHORT).show();
                } else {
                    scaleWdith *= zoomin;
                    scaleHeight *= zoomin;
                    resizeImg();
                }

            }

        });

        zControls.setOnZoomOutClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                smallImg();

            }

            private void smallImg() {
                width_one = bitmap.getWidth();
                height_one = bitmap.getHeight();

                scaleWdith *= zoomout;
                scaleHeight *= zoomout;
                resizeImg();
                Toast.makeText(CBI_Activity.this,
                        "縮小," + scaleWdith + "," + scaleHeight,
                        Toast.LENGTH_SHORT).show();

            }
        });

    }

    public void resizeImg() {

        Matrix matrix = new Matrix();
        matrix.postScale(scaleWdith, scaleHeight);
        Bitmap bitmapTwo = Bitmap.createBitmap(bitmap, 0, 0, width_one,
                height_one, matrix, true);
        if (id == 0) {
            // 第一次刪除
            layout.removeView(img);
        } else {
            layout.removeView(CBI_Activity.this.findViewById(id));
        }
        id++;
        ImageView imgTwo = new ImageView(CBI_Activity.this);
        imgTwo.setImageBitmap(bitmapTwo);
        imgTwo.setId(id);
        imgTwo.setOnTouchListener(listener);
        layout.addView(imgTwo, 3);
        CBI_Activity.this.setContentView(layout);
        Toast.makeText(CBI_Activity.this,
                "放大," + scaleWdith + "," + scaleHeight, Toast.LENGTH_SHORT)
                .show();

    }

    private final static int NONE = 0;
    private final static int DRAG = 1;// 一隻手
    private final static int ZOOM = 2;// 多點觸摸
    private Matrix matrix = new Matrix();// 保存拖拉變化的矩陣
    private Matrix curMatrix = new Matrix();// 保存當前的矩陣
    private PointF startPoint = new PointF();
    private PointF endPoint;
    private int mode = 0;
    private float startdistance;

    class ImageViewTouchListener implements OnTouchListener {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            // 一隻手指情況
            // 兩隻手情況 起始點和終點
            switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:// 單隻手指按下
                curMatrix.set(matrix);
                startPoint.set(event.getX(), event.getY());
                mode = DRAG;
                break;
            case MotionEvent.ACTION_MOVE:
                if (mode == DRAG) {
                    // 獲取結束點的座標
                    float dx = event.getX() - startPoint.x;
                    float dy = event.getY() - startPoint.y;
                    matrix.set(curMatrix);
                    matrix.postTranslate(dx, dy);// 移動到指定的位置
                } else if (mode == ZOOM) {
                    float distance = distance(event);
                    if (distance > 5f) {
                        matrix.set(curMatrix);
                        float scale = distance / startdistance;
                        matrix.preScale(scale, scale, endPoint.x, endPoint.y);
                    }
                }
                break;
            case MotionEvent.ACTION_POINTER_DOWN:// 如果一隻手指按下屏幕,後續
                startdistance = distance(event);
                if (startdistance > 5f) {
                    // 兩手指間的距離像素>5,認爲多點
                    mode = ZOOM;
                    curMatrix.set(matrix);
                    endPoint = getMidPoint(event);
                }
                break;
            case MotionEvent.ACTION_UP:// 最後一隻離開屏幕觸發的事件
                break;
            case MotionEvent.ACTION_POINTER_UP:// 還有一隻手指沒有離開
                mode = NONE;
                break;
            }
            if (id == 0) {
                layout.removeView(img);
            } else {
                layout.removeView(CBI_Activity.this.findViewById(id));
            }
            id++;
            CustomomImageView imgView = new CustomomImageView(
                    CBI_Activity.this, matrix);
            imgView.setImageMatrix(matrix);
            imgView.setId(id);
            imgView.setOnTouchListener(listener);
            layout.addView(imgView, 2);
            return true;
        }

        private PointF getMidPoint(MotionEvent event) {
            float eX = (event.getX(1) - event.getX(0)) / 2;
            float eY = (event.getY(1) - event.getY(0)) / 2;
            return new PointF(eX, eY);
        }

    }

    private float distance(MotionEvent event) {
        float eX = event.getX(1) - event.getX(0);
        float eY = event.getY(1) - event.getY(0);
        return FloatMath.sqrt(eX * eX + eY * eY);
    }

    class CustomomImageView extends ImageView {
        private Matrix mMatrix = new Matrix();

        public CustomomImageView(Context context, Matrix mMatrix) {
            super(context);
            this.mMatrix = mMatrix;

        }

        @Override
        protected void onDraw(Canvas canvas) {
            // 畫出變換後的圖像
            canvas.drawBitmap(bitmap, mMatrix, null);
            super.onDraw(canvas);
        }

    }

    public void big(View v) {// 標籤中添加點擊事件
        Matrix matrix = new Matrix();
        scaleWdith *= zoomin;
        scaleHeight *= zoomin;
        matrix.postScale(scaleWdith, scaleHeight);
        matrix.setRotate(120);
        matrix.setTranslate(300, 300);
        if (id == 0) {
            layout.removeView(img);
        } else {
            layout.removeView(this.findViewById(id));
        }
        id++;
        CustomomImageView imgView = new CustomomImageView(this, matrix);
        imgView.setImageMatrix(matrix);
        imgView.setId(id);
        layout.addView(imgView, 2);

        // setContentView(layout);
        Toast.makeText(CBI_Activity.this, "執行了", Toast.LENGTH_SHORT).show();

    }

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章