文章来自于
SurfaceView的基本使用
Android中的SurfaceView详解
目录
- SurfaceView的引入
- SurfaceView和View的区别
- SurfaceView需要实现的接口
- SurfaceView的简单实现
1.SurfaceView的引入
Android提供了View来进行绘图处理。
在大部分情况下,View都能满足绘图需求。
大家都知道View是通过刷新来重绘视图,Android系统通过发出VSYNC信号来进行屏幕的重绘,刷新的间隔时间为16ms。如果在16ms内View完成了你所需要执行的所有操作,那么用户在视觉上,就不会产生卡顿的感觉;
反之,如果操作的逻辑过多时,就会掉帧从而使得用户感觉到卡顿。特别的需要频繁刷新的界面上,如游戏(60FPS以上),就会不断阻塞主线程,从而导致界面卡顿。
而Android提供了SurfaceView来解决这种情况。
2.SurfaceView和View的区别
则如果一个View需要频繁的刷新,或者在刷新时数据处理量大(可能引起卡顿),可以考虑使用SurfaceView来替代View。
3. SurfaceView需要实现的接口
需要实现两个接口
- SurfaceHolder.CallBack
- Runnable
① 第一个接口中需要实现的方法分别对应于SurfaceView的生命周期,即创建、改变和销毁。
//Surface的生命周期
@Override
public void surfaceCreated(SurfaceHolder holder) {
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
② 第二个接口需要实现run方法,用于在子线程中进行draw操作。
public void run() {
}
4. SurfaceView的简单实现
package com.pignet.surfaceviewdemo;
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
/**
* Created by DB on 2017/6/9.
*/
public class SurfaceViewTemplate extends SurfaceView implements SurfaceHolder.Callback,Runnable{
private SurfaceHolder mHolder;
private Canvas mCanvas;
private boolean mIsDrawing;
//构造方法
public SurfaceViewTemplate(Context context) {
super(context);
initView();
}
public SurfaceViewTemplate(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SurfaceViewTemplate(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
private void initView() {
mHolder=getHolder();
//注册回调方法
mHolder.addCallback(this);
//设置一些参数方便后面绘图
setFocusable(true);
setFocusableInTouchMode(true);
this.setKeepScreenOn(true);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
mIsDrawing=true;
new Thread(this).start();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mIsDrawing=false;
}
@Override
public void run() {
while (mIsDrawing){
draw();
//通过线程休眠以控制刷新速度
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void draw() {
try {
//通过lockCanvas()方法获得Canvas对象
mCanvas=mHolder.lockCanvas();
//初始化画布并在画布上画一些东西
//在子线程中使用Canvas对象进行绘制
}catch (Exception e){
}finally {
//判断画布是否为空,从而避免黑屏情况
if(mCanvas!=null){
//使用unlockCanvasAndPost()方法将画布内容进行提交
mHolder.unlockCanvasAndPost(mCanvas);
}
}
}
}
网友评论