surfaceview使用详解

SurfaceView是Android提供的一个View子类,用于处理视图的绘制、更新和线程控制等操作。在安卓应用中,SurfaceView被广泛应用于游戏、动画、视频播放等需要高性能绘制的场景。本文将对SurfaceView的使用方法进行详细介绍并给出案例说明。

一、SurfaceView的使用方法

1.1 SurfaceView与普通View的区别

普通View相关的绘制操作是在主线程(UI线程)中进行的,绘制的内容是放在View的缓存区中,最终在主线程的UI环节中进行合成输出。这样就导致了,在绘制完成前,各种干扰或者错误操作都会影响到视图的呈现。在对于需要大量绘制的场景,如游戏或者视频播放中,这样的方式就显得效率低下,无法满足高速绘制的需求。

而SurfaceView则是创建了一个必要的品质条目,提供了一个完整的双缓冲机制。SurfaceView利用了SurfaceHolder.Callback接口,可以在子线程中实现绘制并直接显示到屏幕中。这种方式称为“离屏渲染”(Offscreen Render),意思是在绘制时使用一个独立的缓冲区,不使用主线程中的视图缓存区。

1.2 SurfaceView的使用步骤

使用SurfaceView需要完成以下步骤:

1.2.1 在布局文件中定义SurfaceView

```xml

android:id="@+id/surfaceView"

android:layout_width="match_parent"

android:layout_height="match_parent" />

```

1.2.2 获取SurfaceHolder对象

```java

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

SurfaceHolder holder = surfaceView.getHolder();

```

1.2.3 设置SurfaceHolder.Callback监听

```java

holder.addCallback(new SurfaceHolder.Callback() {

@Override

public void surfaceCreated(SurfaceHolder holder) {

// SurfaceView创建时执行操作

}

@Override

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

// SurfaceView改变时执行操作

}

@Override

public void surfaceDestroyed(SurfaceHolder holder) {

// SurfaceView销毁时执行操作

}

});

```

1.2.4 开始绘制

在surfaceCreated()回调方法中开启一个线程进行绘制操作。在绘制过程中,使用Canvas绘制,并通过SurfaceHolder.lockCanvas()方法获取Surface画布。绘制完成后,通过SurfaceHolder.unlockCanvasAndPost()方法将Surface画布提交到屏幕上进行渲染。

```java

public void surfaceCreated(SurfaceHolder holder) {

new Thread(new Runnable() {

@Override

public void run() {

while (true) {

// 在此进行绘制操作

// 1. 获取Surface画布

Canvas canvas = holder.lockCanvas();

// 2. 绘制内容

// 3. 将内容提交到屏幕显示

holder.unlockCanvasAndPost(canvas);

}

}

}).start();

}

```

二、SurfaceView的案例说明

2.1 如何在SurfaceView上绘制一个图形?

首先,在SurfaceView的布局文件中定义SurfaceView,并在代码中获取SurfaceHolder对象。

```xml

android:id="@+id/surfaceView"

android:layout_width="match_parent"

android:layout_height="match_parent" />

```

```java

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

SurfaceHolder holder = surfaceView.getHolder();

```

然后,在SurfaceHolder.Callback监听器的surfaceCreated()回调方法中开启一个线程进行绘制操作。

```java

public void surfaceCreated(SurfaceHolder holder) {

new Thread(new Runnable() {

@Override

public void run() {

while (true) {

// 1. 获取Surface画布

Canvas canvas = holder.lockCanvas();

// 2. 绘制内容

Paint paint = new Paint();

paint.setColor(Color.RED);

canvas.drawCircle(200, 200, 100, paint);

// 3. 将内容提交到屏幕显示

holder.unlockCanvasAndPost(canvas);

}

}

}).start();

}

```

在该代码中,我们绘制了一个红色的圆形,并将其绘制在了Canvas对象上。最后,通过SurfaceHolder.unlockCanvasAndPost()方法将绘制的内容提交到屏幕上进行显示。

2.2 如何在SurfaceView上实现动画?

使用SurfaceView实现动画可以利用“双缓冲”的机制,利用第二个缓存区保存当前帧的绘制内容,由此实现流畅的动画效果。

具体实现方法是:在SurfaceHolder.Callback监听器的surfaceCreated()回调方法中启动一个线程,每次循环都在第二个缓冲区中绘制下一帧,每绘制完一帧时让它休眠一定的时间(一般是16毫秒),然后让第二个缓存区与第一个缓存区互换,这样就可以实现动画效果。

```java

public void surfaceCreated(SurfaceHolder holder) {

new Thread(new Runnable() {

@Override

public void run() {

while (true) {

// 1. 获取第二个Surface画布

Canvas nextCanvas = holder.lockCanvas();

// 2. 绘制下一帧

// 3. 将第二个画布绘制到屏幕上

holder.unlockCanvasAndPost(nextCanvas);

// 4. 等待下一次绘制

try {

Thread.sleep(16);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}).start();

}

```

2.3 如何在SurfaceView上播放视频?

SurfaceView是安卓系统提供的专门用于视频播放的控件,在打开视频文件后,将得到一个预览的Surface对象,持有这个Surface对象可以实现视频的播放、暂停等操作。

```java

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

MediaPlayer mediaPlayer = new MediaPlayer();

try {

AssetFileDescriptor afd = getAssets().openFd("demo.mp4");

mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());

mediaPlayer.prepareAsync();

mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {

public void onPrepared(MediaPlayer mp) {

SurfaceHolder holder = surfaceView.getHolder();

mediaPlayer.setDisplay(holder);

mediaPlayer.start();

}

});

} catch (IOException e) {

e.printStackTrace();

}

```

在代码中,我们使用MediaPlayer对象进行视频播放,将视频展示在SurfaceView上。在MediaPlayer.OnPreparedListener的回调方法中,通过setDisplay()方法将视频预览的Surface对象设置到MediaPlayer中。

三、总结

本文介绍了SurfaceView的使用方法与示例说明。SurfaceView的使用可以有效提升视图、动画、视频等内容的绘制效率,同时也需要注意其线程控制等细节操作。在使用时应结合具体需求进行实际调用,以达到最优效果。 如果你喜欢我们三七知识分享网站的文章, 欢迎您分享或收藏知识分享网站文章 欢迎您到我们的网站逛逛喔!https://www.37seo.cn/

点赞(94) 打赏

评论列表 共有 0 条评论

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