Surface与SurfaceView、SurfaceHolder

一、Surface

Surface是Android系统提供的一个用于绘制图像的基础类,可以用于显示来自硬件加速器、本地代码或者其他进程的图像。通过SurfaceView或者TextureView来展示Surface所绘制的图像。

Surface提供了两个作用:一是作为图像模板,用来发送给窗口进行显示;二是提供一个绘制区域,让我们可以在其上进行图像的绘制操作。具有可见性(Visible)和背景透明度等属性设置。

二、SurfaceView

SurfaceView是Android SDK中提供的一种用于绘图的View容器。与普通的View不同,SurfaceView并不在UI主线程中进行绘制;相反,它自己拥有一个非UI线程和一个特殊的Surface,绘图请求都通过这个非UI线程进行处理。这种方式可以保证视图的刷新不会受到UI线程的延迟影响,从而实现了更加流畅的绘图体验。

三、SurfaceHolder

SurfaceHolder是Surface的一个管理类,它提供了控制Surface大小和格式、像素的锁定、解锁等便捷的方法。在进行Surface绘图时,必须首先通过SurfaceHolder获取到Surface对象,以进行后续的绘图操作。

四、SurfaceView的使用方法

1.在布局文件中添加SurfaceView:

```xml

...>

android:id="@+id/surfaceView"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:focusable="true" />

```

2.在Activity或者Fragment中获取SurfaceView的Holder对象:

```java

SurfaceView surfaceView = findViewById(R.id.surfaceView);

SurfaceHolder holder = surfaceView.getHolder();

```

3.为SurfaceView的Holder添加回调方法:

```java

holder.addCallback(new SurfaceHolder.Callback() {

// Surface创建时调用

@Override

public void surfaceCreated(SurfaceHolder holder) {

// 在Surface创建时,开启一个线程进行绘图操作

startDrawThread();

}

// Surface改变时调用

@Override

public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

}

// Surface销毁时调用

@Override

public void surfaceDestroyed(SurfaceHolder holder) {

// 停止绘图线程

stopDrawThread();

}

});

```

4.Surface绘图:

```java

Canvas canvas = holder.lockCanvas(); // 获取画布,并锁定像素

// 在画布上进行绘图操作

...

holder.unlockCanvasAndPost(canvas); // 解除锁定像素,并提交绘图内容

```

五、案例说明

下面是一个简单的案例,实现了利用SurfaceView和SurfaceHolder进行绘图的效果。

```java

public class DrawSurfaceViewActivity extends AppCompatActivity {

private SurfaceView surfaceView;

private SurfaceHolder holder;

private DrawThread drawThread;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_draw_surface_view);

surfaceView = findViewById(R.id.surfaceView);

holder = surfaceView.getHolder();

holder.addCallback(new SurfaceHolder.Callback() {

@Override

public void surfaceCreated(SurfaceHolder holder) {

drawThread = new DrawThread(holder);

drawThread.start();

}

@Override

public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

}

@Override

public void surfaceDestroyed(SurfaceHolder holder) {

boolean retry = true;

drawThread.setRunning(false);

while (retry) {

try {

drawThread.join();

retry = false;

} catch (InterruptedException e) {

//do nothing

}

}

}

});

}

private static class DrawThread extends Thread {

private final SurfaceHolder surfaceHolder;

private boolean isRunning;

public DrawThread(SurfaceHolder surfaceHolder) {

this.surfaceHolder = surfaceHolder;

this.isRunning = true;

}

//停止绘图线程

public void setRunning(boolean running) {

isRunning = running;

}

@Override

public void run() {

while (isRunning) {

try {

Thread.sleep(50);

} catch (InterruptedException e) {

e.printStackTrace();

}

Canvas canvas = surfaceHolder.lockCanvas();

if (canvas == null) {

continue;

}

canvas.drawColor(Color.WHITE);

Paint paint = new Paint();

paint.setAntiAlias(true);

paint.setColor(Color.RED);

canvas.drawText("Hello, SurfaceView!", 100, 100, paint);

paint.setColor(Color.GREEN);

paint.setStyle(Paint.Style.STROKE);

paint.setStrokeWidth(5);

RectF rect = new RectF(200, 200, 700, 500);

canvas.drawRoundRect(rect, 30, 30, paint);

surfaceHolder.unlockCanvasAndPost(canvas);

}

}

}

}

```

在该案例中,我们通过SurfaceView和SurfaceHolder实现了一个绘图线程,按照50ms的频率不断地在Surface上进行绘图操作,绘制了一段文本和一个圆角矩形。 如果你喜欢我们三七知识分享网站的文章, 欢迎您分享或收藏知识分享网站文章 欢迎您到我们的网站逛逛喔!https://www.37seo.cn/

点赞(88) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿
发表
评论
返回
顶部