Android:實現最簡單的單指移動、雙指縮放的圖片組件

來源:互聯網
上載者:User

標籤:android   自訂群組件   單指移動多指縮放   

本例實現了最簡單的單指移動、雙指縮放的圖片組件,如下:

     


     


功能:

1.單指移動,雙指縮放。

2.可控制縮放範圍,防止過大或過小;初始化時自動縮放至組件大小,並置中顯示。

3.邊界控制,防止圖片“移出去了”。

4.可使用在xml中,並自動適應組件大小。

5.代碼簡潔!!!


核心代碼:DragScaleView.java

package com.sina.simplegestureimage;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Paint;import android.support.annotation.NonNull;import android.util.AttributeSet;import android.view.GestureDetector;import android.view.MotionEvent;import android.view.ScaleGestureDetector;import android.view.View;/** * DragScaleView * Created by hanswim on 15-1-23. */public class DragScaleView extends View {    //監聽圖片縮放    private ScaleGestureDetector mScaleDetector;    //監聽圖片移動    private GestureDetector mGestureDetector;    //當前的縮放比例    private float mScaleFactor = 1.0f;    public DragScaleView(Context context) {        super(context);    }    public DragScaleView(Context context, AttributeSet attrs) {        super(context, attrs);        init(context);    }    public DragScaleView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    private void init(Context context) {        mScaleDetector = new ScaleGestureDetector(context, new SimpleScaleListenerImpl());        mGestureDetector = new GestureDetector(context, new SimpleGestureListenerImpl());    }    private Paint bmpPaint = new Paint();    //圖片資源    private Bitmap bmp;    //圖片的寬高    private int bmpWidth, bmpHeight;    public void setImageResource(int id) {        bmp = BitmapFactory.decodeResource(getResources(), id);        bmpWidth = bmp.getWidth();        bmpHeight = bmp.getHeight();        initViewSize();        invalidate();    }    //繪製圖片的起始位置    private float mPosX, mPosY;    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        if (bmp == null) {            return;        }        if (!hasGetViewSize) {            initViewSize();        }        canvas.save();        checkBounds();        //以圖片的中心為基點進行縮放        canvas.scale(mScaleFactor, mScaleFactor, mPosX + bmpWidth / 2, mPosY + bmpHeight / 2);        canvas.drawBitmap(bmp, mPosX, mPosY, bmpPaint);        canvas.restore();    }//    private float lastX, lastY;//    private static final int INVALID_POINTER_ID = -1;//    private int mActivePointerId = INVALID_POINTER_ID;    @Override    public boolean onTouchEvent(@NonNull MotionEvent event) {        //雙指縮放        mScaleDetector.onTouchEvent(event);        //單指移動        mGestureDetector.onTouchEvent(event);        return true;        //也可以自己實現“單指移動圖片”        /*        int action = MotionEventCompat.getActionMasked(event);        switch (action) {            case MotionEvent.ACTION_DOWN: {                final int pointerIndex = MotionEventCompat.getActionIndex(event);                mActivePointerId = MotionEventCompat.getPointerId(event, pointerIndex);                lastX = event.getX();                lastY = event.getY();                break;            }            case MotionEvent.ACTION_MOVE: {                // Find the index of the active pointer and fetch its position                final int pointerIndex = MotionEventCompat.findPointerIndex(event, mActivePointerId);                float currentX = MotionEventCompat.getX(event, pointerIndex);                float currentY = MotionEventCompat.getY(event, pointerIndex);                mPosX += (currentX - lastX);                mPosY += (currentY - lastY);                invalidate();                lastX = currentX;                lastY = currentY;                break;            }            case MotionEvent.ACTION_POINTER_UP: {                final int pointerIndex = MotionEventCompat.getActionIndex(event);                final int pointerId = MotionEventCompat.getPointerId(event, pointerIndex);                if (pointerId == mActivePointerId) {                    // This was our active pointer going up. Choose a new                    // active pointer and adjust accordingly.                    final int newPointerIndex = pointerIndex == 0 ? 1 : 0;                    lastX = MotionEventCompat.getX(event, newPointerIndex);                    lastY = MotionEventCompat.getY(event, newPointerIndex);                    mActivePointerId = MotionEventCompat.getPointerId(event, newPointerIndex);                }                break;            }            case MotionEvent.ACTION_UP: {                mActivePointerId = INVALID_POINTER_ID;                break;            }        }        */    }    /**     * 不能超出邊界.     * 原則是:圖片較小時任意一條邊都不能出了邊界,圖片較大任意一條邊都不能進入邊界。寬度和高度分別獨立計算。     */    private void checkBounds() {        if (mScaleFactor > widthScale) {            //寬度方向已經填滿            mPosX = Math.min(mPosX, (mScaleFactor - 1) * (bmpWidth / 2));            mPosX = Math.max(mPosX, viewWidth - bmpWidth - (mScaleFactor - 1) * (bmpWidth / 2));        } else {            mPosX = Math.max(mPosX, (mScaleFactor - 1) * (bmpWidth / 2));            mPosX = Math.min(mPosX, viewWidth - bmpWidth - (mScaleFactor - 1) * (bmpWidth / 2));        }        if (mScaleFactor > heightScale) {            //高度方向已經填滿            mPosY = Math.min(mPosY, (mScaleFactor - 1) * (bmpHeight / 2));            mPosY = Math.max(mPosY, viewHeight - bmpHeight - (mScaleFactor - 1) * (bmpHeight / 2));        } else {            mPosY = Math.max(mPosY, (mScaleFactor - 1) * (bmpHeight / 2));            mPosY = Math.min(mPosY, viewHeight - bmpHeight - (mScaleFactor - 1) * (bmpHeight / 2));        }    }    private int viewWidth, viewHeight;    //組件尺寸只需要擷取一次    private boolean hasGetViewSize;    private void initViewSize() {        viewWidth = getWidth();        viewHeight = getHeight();        if (viewWidth > 0 && viewHeight > 0) {            hasGetViewSize = true;            widthScale = 1.0f * viewWidth / bmpWidth;            heightScale = 1.0f * viewHeight / bmpHeight;            //初始縮放比例(使組件剛好鋪滿)            mScaleFactor = Math.min(widthScale, heightScale);            //初始時圖片置中繪製            mPosX = viewWidth / 2 - bmpWidth / 2;            mPosY = viewHeight / 2 - bmpHeight / 2;        }    }    /**     * 寬度和高度放大多少倍時,剛好填滿此方向的螢幕     */    private float widthScale, heightScale;    //縮放    private class SimpleScaleListenerImpl extends ScaleGestureDetector.SimpleOnScaleGestureListener {        @Override        public boolean onScale(ScaleGestureDetector detector) {            mScaleFactor *= detector.getScaleFactor();            //縮放倍數範圍:0.3~3            mScaleFactor = Math.max(0.3f, Math.min(mScaleFactor, 3.0f));            invalidate();            return true;        }    }    //移動    private class SimpleGestureListenerImpl extends GestureDetector.SimpleOnGestureListener {        @Override        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {            mPosX -= distanceX;            mPosY -= distanceY;            invalidate();            return true;        }    }}

在Activity中使用:

@Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.drag_scale);        RadioButton landscapeRBtn = (RadioButton) findViewById(R.id.radio_landscape);        final DragScaleView dragView = (DragScaleView) findViewById(R.id.drag_scale_view);        dragView.setImageResource(R.drawable.cat_boarder);        landscapeRBtn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {            @Override            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {                if (isChecked) {                    dragView.setImageResource(R.drawable.cat_boarder);                } else {                    dragView.setImageResource(R.drawable.cat_boarder_p);                }            }        });    }

======

原始碼即將奉上,盡情期待。


Android:實現最簡單的單指移動、雙指縮放的圖片組件

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.