認識事物都遵循由簡入繁的順序,下面我們想實現一個控件或者一個布局的縮放,先從簡單的例子開始吧,我們就以縮放圖片做入門。
效果圖:
一、要求
利用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有可被點擊的功能,縮放后不能丟失該功能)