縮放系列(一):一個很好的bitmap手勢縮放demo(多點觸控)


認識事物都遵循由簡入繁的順序,下面我們想實現一個控件或者一個布局的縮放,先從簡單的例子開始吧,我們就以縮放圖片做入門。

效果圖:

 

一、要求

利用ScaleGestureDetector這個類實現圖片縮放。

二、代碼

public class MainActivity extends ActionBarActivity {
    private SurfaceView mSurfaceView = null;
    private SurfaceHolder mSurfaceHolder = null;
    private ScaleGestureDetector mScaleGestureDetector = null;
    private Bitmap mBitmap = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mSurfaceView = (SurfaceView) this.findViewById(R.id.surfaceview);
        mSurfaceHolder = mSurfaceView.getHolder();
        mScaleGestureDetector = new ScaleGestureDetector(this,
                new ScaleGestureListener());

        mSurfaceView.post(new Runnable() {
            
            @Override
            public void run() {
                
                mBitmap = BitmapFactory.decodeResource(getResources(),
                        R.drawable.guanmjie);
                // 鎖定整個SurfaceView
                Canvas mCanvas = mSurfaceHolder.lockCanvas();
                // 畫圖
                mCanvas.drawBitmap(mBitmap, 0f, 0f, null);
                // 繪制完成,提交修改
                mSurfaceHolder.unlockCanvasAndPost(mCanvas);
                // 重新鎖一次
                mSurfaceHolder.lockCanvas(new Rect(0, 0, 0, 0));
                mSurfaceHolder.unlockCanvasAndPost(mCanvas);
            }
        });

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // 返回給ScaleGestureDetector來處理
        return mScaleGestureDetector.onTouchEvent(event);
    }

    public class ScaleGestureListener implements
            ScaleGestureDetector.OnScaleGestureListener {

        private float scale;
        private float preScale = 1;// 默認前一次縮放比例為1

        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            // TODO Auto-generated method stub

            Matrix mMatrix = new Matrix();
            float previousSpan = detector.getPreviousSpan();
            float currentSpan = detector.getCurrentSpan();
            if (currentSpan < previousSpan) {
                // 縮小
                // scale = preScale-detector.getScaleFactor()/3;
                scale = preScale - (previousSpan - currentSpan) / 1000;
            } else {
                // 放大
                // scale = preScale+detector.getScaleFactor()/3;
                scale = preScale + (currentSpan - previousSpan) / 1000;
            }
            mMatrix.setScale(scale, scale);

            // 鎖定整個SurfaceView
            Canvas mCanvas = mSurfaceHolder.lockCanvas();
            // 清屏
            mCanvas.drawColor(Color.BLACK);
            // 畫縮放后的圖
            mCanvas.drawBitmap(mBitmap, mMatrix, null);
            // 繪制完成,提交修改
            mSurfaceHolder.unlockCanvasAndPost(mCanvas);
            // 重新鎖一次
            mSurfaceHolder.lockCanvas(new Rect(0, 0, 0, 0));
            mSurfaceHolder.unlockCanvasAndPost(mCanvas);

            return false;
        }

        @Override
        public boolean onScaleBegin(ScaleGestureDetector detector) {
            // 一定要返回true才會進入onScale()這個函數
            return true;
        }

        @Override
        public void onScaleEnd(ScaleGestureDetector detector) {
            preScale = scale;//記住本次的縮放后的圖片比例
        }
    }
}

activity_main.xml如下:

<?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
     android:orientation="vertical" >
    
     <SurfaceView
         android:id="@+id/surfaceview"
         android:layout_width="fill_parent"
         android:layout_height="fill_parent"
         />
 
 </LinearLayout>

  

 

總結:本例利用了matrix和canvas,對圖片進行縮放;本demo還可以改造,不需matrix和canvas,在獲得scale值之后對其他控件等縮放都可以!功能強大!而且簡單明了,完全無bug!

下面是一個功能強大的改造的例子:

可以實現以下需求:

1.兩個手指進行縮放布局

2.所有子控件也隨着縮放,

3.子控件該有的功能不能丟失(像button有可被點擊的功能,縮放后不能丟失該功能)

鏈接:http://www.cnblogs.com/johnsonwei/p/5830277.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM