SurfaceView继承自View,他们都能进行动画绘制,但是对于经常要刷新的动画,我们还是首选SurfaceView
1. View是在主UI线程中进行图画绘制,这样有时候会造成线程阻塞从而出现卡顿甚至崩溃的问题。而SurfaceView是在子线程中进行创建的,只要在主UI线程中调用,就可以实现同样的效果。并且这种方式绘制的动画,不会对主UI线程造成太大的负担(至少相比View),因为线程一次只能执行一件事情,故我们也理解理解我们的主UI线程吧。
2. SurfaceView支持连续多次的画面绘制操作。由于动画是连续的一个过程,故我们需要时刻进行动画的更新,在这里表现为重新绘制,SurfaceView是在子线程中工作的,因此它对我们的主UI线程影响不大,而View在主线程工作,倘若每次都进行重新绘制,主UI线程的其他工作就需要暂时放一放了,这样可能会造成界面卡顿等情况,非常影响用户体验,因此我们也通常选择用SurfaceView进行图形动画绘制。
3. SurfaceView在底层实现了双缓冲机制。其实由于SurfaceView适合多次图形动画绘制(即经常刷新)和它在底层实现的双缓冲机制,在做游戏开发的时候经常能够看到它的身影。
接下来上SurfaceView的使用案例(个人学习用的小Demo)
public class SurfaceViewTestextends SurfaceViewimplements SurfaceHolder.Callback,View.OnClickListener{
private Paintpaint =new Paint();
private float left =0; //物体的左边界与屏幕左侧的距离,以下同理
private float top =0;
private float width =150; //可理解为物体右边界相对于物体左边界的距离
private float height =150;
private float offsetX =8; //物体每次在水平方向上的偏移量
private float offsetY =8;
private boolean flag =false;
public SurfaceViewTest(Context context) {
super(context);
paint.setColor(Color.RED);
getHolder().addCallback(this);
this.setOnClickListener(this);
}
public void draw(){
Canvas canvas = getHolder().lockCanvas();
canvas.drawColor(Color.WHITE);
canvas.drawRect(left,top,width +left,height +top,paint);
left +=offsetX;
top +=offsetY;
if(left<0){
offsetX = Math.abs(offsetX);
}
if(top<0){
offsetY = Math.abs(offsetY);
}
if(left>getWidth() -width){
offsetX = -Math.abs(offsetX);
}
if(top>getHeight() -height){
offsetY = -Math.abs(offsetY);
}
getHolder().unlockCanvasAndPost(canvas);
}
Handlerhandler =new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
draw();
handler.sendEmptyMessageDelayed(0,20);
}
};
public void start(){
handler.sendEmptyMessage(0);
}
public void stop(){
handler.removeMessages(0);
}
public void onClick(View v){
if(!flag){
start();
flag =true;
}else{
s top();
flag =false;
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
start();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
}
下面上效果图(技术有限,没办法上动图或者视频,总之是一个四处碰撞的矩形啦):