Surface和SurfaceView以及SurfaceHolder的认识及使用

简介: MainActivity如下: package cn.testcleancanvas;import android.os.Bundle;import android.

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>



 

相关文章
|
11月前
|
API 异构计算
SurfaceView 和 TextureView
SurfaceView 和 TextureView
277 0
|
12月前
|
前端开发 Android开发
SurfaceView的那点事儿
SurfaceView的那点事儿
91 0
|
Android开发
Android Reveal圆形Activity转场动画
一、效果 图片较大无法上传~~ 地址:https://user-gold-cdn.xitu.io/2018/11/2/166d4b91aecdf577?imageslim 二、知识点 CircularReveal动画、透明主题、转场动画(非必须) 三、方案 假设有两个Activity A和B。
2009 0
|
API Android开发 容器
Android Camera2拍照(一)——使用SurfaceView
原文:Android Camera2拍照(一)——使用SurfaceView Camera2 API简介 Android 从5.
3480 0
|
Android开发 API
Android Camera2 拍照(二)——使用TextureView
原文:Android Camera2 拍照(二)——使用TextureView 上一篇博文简单介绍了使用Camera2 API拍摄照片,并使用SurfaceView作为预览界面。
2868 0
|
前端开发 Android开发