MainActivity如下:
package cn.testcleancanvas; import android.os.Bundle; import android.app.Activity; /** * Demo描述: * 0 Surface和SurfaceView以及SurfaceHolder的认识及使用 * 1 Canvas清屏的实现 * 2 在SurfaceView上不断绘制图片 * 所绘制的图片在屏幕上的X轴值不断变化,所以给人感觉该图片在不断地移动. * 所以给我们一个启示:看到一个图片在屏幕上不停地移动不一定是利用动画做出来 * 的效果,还有可能是draw出来的 * * 笔记摘要: * 1 Surface用于管理数据,SurfaceView用于展示数据 * 2 SurfaceHolder是一个接口,其作用相当于是Surface的监听器. * SurfaceHolder提供了访问和控制SurfaceView背后的Surface的相关方法. * 即SurfaceHolder通过三个回调方法可知Surface的创建、销毁或者改变 * 可通过SurfaceView中的方法getHolder()获得SurfaceView所对应的Surface所对应的SurfaceHolder * 3 SurfaceView是在一个新线程中绘制图像,而不是在UI线程 * * 参考资料: * 0 http://blog.csdn.net/pathuang68/article/details/7351317 * 1 http://blog.csdn.net/yanzi1225627/article/details/8236309 * 2 http://blog.csdn.net/yuanlong_zheng/article/details/7592457 * Thank you very much * */ public class MainActivity extends Activity { private ImageMovingSurfaceView mImageMovingSurfaceView; private PhotoMovingSurfaceView mPhotoMovingSurfaceView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //方式一: mImageMovingSurfaceView= new ImageMovingSurfaceView(MainActivity.this); setContentView(mImageMovingSurfaceView); //方式二: // mPhotoMovingSurfaceView= // new PhotoMovingSurfaceView(MainActivity.this); // setContentView(mPhotoMovingSurfaceView); } }
ImageMovingSurfaceView如下:
package cn.testcleancanvas; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.PorterDuffXfermode; import android.graphics.PorterDuff.Mode; import android.view.SurfaceHolder; import android.view.SurfaceHolder.Callback; import android.view.SurfaceView; /** * 参考资料: * 0 http://blog.csdn.net/pathuang68/article/details/7351317 * 1 http://blog.csdn.net/yanzi1225627/article/details/8236309 * 2 http://blog.csdn.net/yuanlong_zheng/article/details/7592457 * * Thank you very much */ public class ImageMovingSurfaceView extends SurfaceView implements Callback { private int lastX=0; private Paint mPaint; private Bitmap mBitmap; private Canvas mCanvas; private boolean isSurfaceRun = true; private SurfaceHolder mSurfaceHolder; private DrawMovingImageThread mDrawMovingImageThread; public ImageMovingSurfaceView(Context context) { super(context); init(); } private void init(){ mPaint=new Paint(); //获取SurfaceView的SurfaceHolder mSurfaceHolder=this.getHolder(); //为SurfaceHolder设置回调 mSurfaceHolder.addCallback(this); mDrawMovingImageThread=new DrawMovingImageThread(); mBitmap=BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher); } //开启线程不断地绘制Bitmap private class DrawMovingImageThread extends Thread{ @Override public void run() { super.run(); while (isSurfaceRun) { drawMovingImage(); try { Thread.sleep(300); } catch (Exception e) { e.printStackTrace(); } } } } private void drawMovingImage(){ //从SurfaceHolder获取画布,并在锁定后开始绘画 mCanvas=mSurfaceHolder.lockCanvas(); if (mCanvas!=null) { //以下四行为清屏的核心代码: Paint paint = new Paint(); paint.setXfermode(new PorterDuffXfermode(Mode.CLEAR)); mCanvas.drawPaint(paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC)); //在每次画之前先进行清屏 mCanvas.drawBitmap(mBitmap, lastX, 40, mPaint); lastX+=20; if (lastX>=370) { lastX=0; } //解锁 mSurfaceHolder.unlockCanvasAndPost(mCanvas); } } //以下三个方法为android.view.SurfaceHolder.Callback接口的实现 @Override public void surfaceCreated(SurfaceHolder arg0) { mDrawMovingImageThread.start(); } @Override public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { } @Override public void surfaceDestroyed(SurfaceHolder arg0) { isSurfaceRun=false; } }
PhotoMovingSurfaceView如下:
package cn.testcleancanvas; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.PorterDuffXfermode; import android.graphics.PorterDuff.Mode; import android.view.SurfaceHolder; import android.view.SurfaceHolder.Callback; import android.view.SurfaceView; /** * 参考资料: * 0 http://blog.csdn.net/pathuang68/article/details/7351317 * 1 http://blog.csdn.net/yanzi1225627/article/details/8236309 * 2 http://blog.csdn.net/yuanlong_zheng/article/details/7592457 * * Thank you very much */ public class PhotoMovingSurfaceView extends SurfaceView implements Callback { private int lastX=0; private Paint mPaint; private Bitmap mBitmap; private Canvas mCanvas; private boolean isSurfaceRun = true; private SurfaceHolder mSurfaceHolder; private DrawMovingImageThread mDrawMovingImageThread; public PhotoMovingSurfaceView(Context context) { super(context); init(); } private void init(){ mPaint=new Paint(); //SurfaceView的方法getHolder() mSurfaceHolder=this.getHolder(); mSurfaceHolder.addCallback(this); mDrawMovingImageThread=new DrawMovingImageThread(); mBitmap=BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher); } //开启线程不断地绘制Bitmap private class DrawMovingImageThread extends Thread{ @Override public void run() { super.run(); while (isSurfaceRun) { drawMovingImage(); try { Thread.sleep(300); } catch (Exception e) { e.printStackTrace(); } } } } private void drawMovingImage(){ mCanvas=mSurfaceHolder.lockCanvas(); if (mCanvas!=null) { //以下四行为清屏的核心代码: Paint paint = new Paint(); paint.setXfermode(new PorterDuffXfermode(Mode.CLEAR)); mCanvas.drawPaint(paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC)); //在每次画之前先进行清屏 mCanvas.drawBitmap(mBitmap, lastX, 40, mPaint); lastX+=20; if (lastX>=370) { lastX=0; } mSurfaceHolder.unlockCanvasAndPost(mCanvas); } } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mDrawMovingImageThread.start(); } //以下三个方法为android.view.SurfaceHolder.Callback接口的实现 @Override public void surfaceCreated(SurfaceHolder holder) { //调用SurfaceView的onDraw()方法 onDraw(null); } @Override public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { } @Override public void surfaceDestroyed(SurfaceHolder arg0) { isSurfaceRun=false; } }
main.xml如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > </RelativeLayout>