缩放系列(一):一个很好的bitmap手势缩放demo(多点触控)

来源:互联网 发布:咫尺网络的区域代理 编辑:程序博客网 时间:2024/05/17 08:07

认识事物都遵循由简入繁的顺序,下面我们想实现一个控件或者一个布局的缩放,先从简单的例子开始吧,我们就以缩放图片做入门。

效果图:


一、要求

利用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有可被点击的功能,缩放后不能丢失该功能)

要实现这几点功能,可以参考:

缩放系列(二):所有子控件也随着缩放、手势缩放、多点触控layout

源码地址:https://github.com/Jszgw/BitmapScale
0 0
原创粉丝点击