一、Surface
Surface是一块屏幕的抽象表示,它允许一个应用程序在屏幕上绘制内容。
在Android系统中,一个Surface可以与一个Canvas或OpenGL ES进行交互,从而在屏幕上显示出图形或动画。Surface提供了一个BufferQueue,其中包含了一组Surface上的图像或动画帧,应用程序可以向这个BufferQueue中添加图像或动画帧,而Surface则会把这些图像或动画帧显示出来。当一个图像或动画帧被显示出来后,它就从BufferQueue中移除了。
二、SurfaceView
SurfaceView是Android系统中用于显示Surface的一种视图控件。它通过一个SurfaceHolder对象来控制Surface的创建、销毁和绘制等操作。
与常规的View控件不同,SurfaceView通过子线程来进行绘制操作,这样可以避免在主线程中进行复杂的绘制操作而导致UI卡顿。同时,SurfaceView提供了onDraw()方法,开发者可以在这个方法中进行自己的绘制操作。
三、SurfaceHolder
SurfaceHolder是SurfaceView内部用于控制Surface的一个接口。通过SurfaceHolder,应用程序可以进行Surface的创建、销毁、锁定、解锁和绘制等操作。
SurfaceHolder提供了三个方法,分别是:
1. getSurface():获取Surface对象。
2. lockCanvas():获取Surface上的Canvas对象,并锁定Surface,这样其他线程就无法访问Surface了。
3. unlockCanvasAndPost():解锁Surface,并把Canvas上的内容提交到Surface中。
具体使用方法如下:
```Java
SurfaceHolder holder = surfaceView.getHolder();
Canvas canvas = holder.lockCanvas();
// 在Canvas上进行绘制操作
holder.unlockCanvasAndPost(canvas);
```
四、使用方法
首先需要在布局文件中定义SurfaceView组件:
```XML
android:layout_width="match_parent" android:layout_height="match_parent"/> ``` 接着在Activity中获取SurfaceView对象,并设置SurfaceHolder.Callback: ```Java SurfaceView surfaceView = findViewById(R.id.surfaceView); surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder holder) { // Surface被创建时调用 } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // Surface尺寸发生改变时调用 } @Override public void surfaceDestroyed(SurfaceHolder holder) { // Surface被销毁时调用 } }); ``` 在surfaceCreated()方法中可以获取SurfaceHolder对象,并使用lockCanvas()方法获取Canvas对象在上面进行绘制操作,并最终使用unlockCanvasAndPost()方法将内容提交到Surface中,代码如下: ```Java @Override public void surfaceCreated(SurfaceHolder holder) { Canvas canvas = holder.lockCanvas(); // 在Canvas上进行绘制操作 holder.unlockCanvasAndPost(canvas); } ``` 注意:在使用完Canvas后一定要解锁Surface,否则其他线程无法访问Surface,并且会出现黑屏等异常情况。 五、案例说明 下面我们来实现一个简单的SurfaceView动画效果,每次刷新Surface时,小球向上移动一段距离。 首先定义一个Ball类,用于表示小球: ```Java public class Ball { public float x; // 小球的x坐标 public float y; // 小球的y坐标 public float radius; // 小球的半径 public Ball(float x, float y, float radius) { this.x = x; this.y = y; this.radius = radius; } } ``` 然后在Activity中定义一个Ball数组,并在surfaceCreated()方法中对小球进行初始化: ```Java public class MainActivity extends AppCompatActivity { private SurfaceView surfaceView; private Ball[] balls = new Ball[10]; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); surfaceView = findViewById(R.id.surfaceView); surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder holder) { // 初始化小球 float radius = 50; float y = surfaceView.getHeight() - radius; float xInterval = (surfaceView.getWidth() - radius * 2) / (balls.length - 1); for (int i = 0; i < balls.length; i++) { float x = radius + i * xInterval; balls[i] = new Ball(x, y, radius); } // 启动子线程不断重绘 new Thread(new Runnable() { @Override public void run() { while (true) { Canvas canvas = null; try { canvas = surfaceView.getHolder().lockCanvas(); synchronized (surfaceView.getHolder()) { draw(canvas); // 在Canvas上进行绘制 } } catch (Exception e) { e.printStackTrace(); } finally { if (canvas != null) { surfaceView.getHolder().unlockCanvasAndPost(canvas); // 提交到Surface中 } } try { Thread.sleep(16); // 控制刷新频率 } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { } }); } private void draw(Canvas canvas) { canvas.drawColor(Color.WHITE); // 用白色清空画布 Paint paint = new Paint(); paint.setColor(Color.RED); for (int i = 0; i < balls.length; i++) { Ball ball = balls[i]; ball.y -= 5; // 让小球向上移动一段距离 canvas.drawCircle(ball.x, ball.y, ball.radius, paint); } } } ``` 在draw()方法中,我们使用Canvas的drawCircle()方法来绘制小球,在每次刷新Surface时让小球向上移动一段距离,从而实现了一个简单的小球动画效果。同时,在surfaceCreated()方法中启动一个子线程,不断地重绘Surface,从而实现动画的播放。 通过这个例子,我们可以了解到Surface、SurfaceView和SurfaceHolder之间的关系,以及如何在SurfaceView中使用Surface进行绘制操作。 如果你喜欢我们三七知识分享网站的文章,
欢迎您分享或收藏知识分享网站文章
欢迎您到我们的网站逛逛喔!https://www.37seo.cn/
发表评论 取消回复