一、Surface
Surface是Android中用于显示图像的一个抽象类,它代表了一个可以被绘制的图像目标。它实现了SurfaceHolder接口,可以提供一个Canvas用于绘制内容。Surface是在窗口系统中表示什么显示什么的一个抽象概念,可以是屏幕、应用界面或者图片等等。
二、SurfaceView
SurfaceView是一个用于绘制2D图形的控件,它继承自View。与普通的View不同的是,SurfaceView有一个独立的Surface,可以在非UI线程中更新图像,因此可以流畅地展现动画效果。使用SurfaceView可以达到更高的帧率,使得图像更加流畅。
三、SurfaceHolder
SurfaceHolder是Surface的持有者,用于管理Surface的生命周期以及控制Surface对外显示。SurfaceHolder提供了一组接口,可用于获取Canvas、设置Surface尺寸、注册Surface.Callback等操作,这样可以对Surface进行更加灵活的控制。
四、使用方法
1.创建SurfaceView并设置大小
在XML布局文件中添加SurfaceView控件,设置它的宽和高,布局文件如下:
```xml
android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 或者在Java代码中动态添加SurfaceView,然后设置它的宽和高,示例代码如下: ```java SurfaceView surfaceView = new SurfaceView(this); FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); surfaceView.setLayoutParams(lp); ``` 2.获取SurfaceHolder 通过SurfaceView获取SurfaceHolder,示例代码如下: ```java SurfaceView surfaceView = findViewById(R.id.surface_view); SurfaceHolder surfaceHolder = surfaceView.getHolder(); ``` 3.注册SurfaceCallback 注册SurfaceCallback,以便回调Surface的生命周期和Surface状态的变化。示例代码如下: ```java SurfaceHolder surfaceHolder = surfaceView.getHolder(); surfaceHolder.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销毁时回调 } }); ``` 4.在Surface中绘制内容 在SurfaceView的回调方法surfaceCreated()中,可以获取到Surface对象,利用Canvas绘制图形。绘制完成后,通过SurfaceHolder.unlockCanvasAndPost()方法提交到Surface中显示。示例代码如下: ```java @Override public void surfaceCreated(SurfaceHolder holder) { Canvas canvas = holder.lockCanvas(); if (canvas != null) { Paint paint = new Paint(); paint.setColor(Color.RED); canvas.drawRect(0, 0, getWidth(), getHeight(), paint); holder.unlockCanvasAndPost(canvas); } } ``` 5.在子线程中更新Surface 在子线程中更新Surface时,需要通过SurfaceHolder.lockCanvas()方法获取到Canvas对象,更新完毕后调用unlockCanvasAndPost()方法提交。示例代码如下: ```java private void updateSurfaceInThread() { new Thread(new Runnable() { @Override public void run() { while (true) { Canvas canvas = holder.lockCanvas(); if (canvas == null) { continue; } Paint paint = new Paint(); paint.setColor(Color.BLUE); canvas.drawRect(0, 0, getWidth(), getHeight(), paint); holder.unlockCanvasAndPost(canvas); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } ``` 6.优化SurfaceView性能 为了获得更好的性能和更平滑的动画效果,我们需要对SurfaceView进行一些优化。例如,在SurfaceView的回调方法中使用ThreadPoolExecutor类来执行耗时操作,或者使用硬件加速等方法来提高绘制效率。另外,我们还可以通过设置SurfaceView的ZOrder来控制它与其他View的叠放顺序,如设置ZOrderOnTop为true可以使得SurfaceView覆盖在其他View之上。 七、案例说明 下面我们来实现一个简单的SurfaceView动画效果,实现圆在SurfaceView中自动移动的功能。 1.创建Circle类 创建一个Circle类,用于存储圆的坐标、半径和颜色等信息,代码如下: ```java public class Circle { private float x; private float y; private float radius; private int color; public Circle(float x, float y, float radius, int color) { this.x = x; this.y = y; this.radius = radius; this.color = color; } public void draw(Canvas canvas) { Paint paint = new Paint(); paint.setAntiAlias(true); paint.setColor(color); canvas.drawCircle(x, y, radius, paint); } public void move(float dx, float dy) { this.x += dx; this.y += dy; } // getter and setter } ``` 2.创建MySurfaceView类 创建一个MySurfaceView类,继承自SurfaceView,并实现SurfaceHolder.Callback接口。在MySurfaceView的构造方法中获取SurfaceHolder,并注册SurfaceHolder的Callback。然后在surfaceCreated()回调方法中启动一个动画线程,用于更新圆的位置,并绘制到SurfaceView中。代码如下: ```java public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback { private static final int CIRCLE_RADIUS = 100; private static final int CIRCLE_COLOR = Color.RED; private SurfaceHolder holder; private boolean isDrawing = true; private Circle circle; public MySurfaceView(Context context) { this(context, null); } public MySurfaceView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public MySurfaceView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { holder = getHolder(); holder.addCallback(this); circle = new Circle(getWidth() / 2, getHeight() / 2, CIRCLE_RADIUS, CIRCLE_COLOR); } @Override public void surfaceCreated(SurfaceHolder holder) { new Thread(new Runnable() { @Override public void run() { float dx = 10; float dy = 10; while (isDrawing) { Canvas canvas = holder.lockCanvas(); if (canvas != null) { circle.move(dx, dy); if (circle.getX() + circle.getRadius() >= getWidth() || circle.getX() - circle.getRadius() <= 0) { dx = -dx; } if (circle.getY() + circle.getRadius() >= getHeight() || circle.getY() - circle.getRadius() <= 0) { dy = -dy; } canvas.drawColor(Color.WHITE); circle.draw(canvas); holder.unlockCanvasAndPost(canvas); } } } }).start(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { isDrawing = false; } } ``` 3.在布局文件中使用MySurfaceView 在布局文件中添加MySurfaceView控件,然后运行应用即可看到一个移动的红色圆。 ```xml android:layout_height="match_parent" /> ``` 总结: 以上就是关于Surface、SurfaceView和SurfaceHolder的详细介绍,以及使用方法和案例说明。它们是Android图形和动画开发中非常重要的基础知识,掌握它们有助于我们开发出更加流畅、高效的应用。 如果你喜欢我们三七知识分享网站的文章,
欢迎您分享或收藏知识分享网站文章
欢迎您到我们的网站逛逛喔!https://www.37seo.cn/
发表评论 取消回复