如何使用surfaceview

SurfaceView是View的继承结构中一个比较特殊的子类,它的作用是提供一个第二线程来完成图形的绘制。因此应用程序不需要等待View的图形绘制,第二线程会异步完成图形的绘制。

SurfaceView实现的步骤:

继续SurfaceView并实现SurfaceHolderCallback接口,该接口提供了SurfaceView创建、属性发生变化、销毁的时间点,那么你可以在适当的时间点完成具体的工作。

在SurfaceView初始化的时候调用SurfaceViewgetHolder()方法获取一个SurfaceHolder,SurfaceHolder用于管理SurfaceView的工作过程。为了让SurfaceHolder起作用,必须为SurfaceHolder添加回调方法(即第一步实现的SurfaceHolderCallback):

[java] view plaincopyprint

SurfaceHolderaddCallBack(SurfaceHolderCallback);

在SurfaceView内创建第二线程的内部类(暂命名为SecondThread),它的主要任务是完成Canvas的图形绘制。为了能让SecondThread获得Canvas实例,必须给SecondThread传递在步骤二中获得的SurfaceHolder。现在就可以通过SurfaceHolderlockCanvas()方法得到Canvas实例,并在Canvas上绘制图形。当图形绘制完成后,必须马上调用SurfaceHolderunlockCanvasAndPost()为Canvas解锁,使其他线程可以使用该画布。

有几个注意点:

每一次通过SurfaceHolder获取的Canvas都会保持上一次绘制的状态。如果需要重新绘制图形,可以通过调用CanvasdrawColor()或CanvasdrawBitmap()来擦除上次遗留的图形。

并不一定只用第二线程来绘制图形,也可以开启第三,第四个线程来绘制图形。

注意线程安全。

不需要像View一样,调用invalidate()方法来指示图形的刷新。

SurfaceView的一个范例:

[java] view plaincopyprint

package comsin90lzcandroidsample;

import javautilArrayList;

import javautilCollections;

import javautilList;

import androidcontentContext;

import androidgraphicsCanvas;

import androidgraphicsColor;

import androidgraphicsPaint;

import androidutilAttributeSet;

import androidutilLog;

import androidviewKeyEvent;

import androidviewSurfaceHolder;

import androidviewSurfaceView;

public class CanvasView extends SurfaceView implements SurfaceHolderCallback {

public static class Point {

private float x;

private float y;

public Point(float x, float y) {

thisx = x;

thisy = y;

}

public float getX() {

return x;

}

public void setX(float x) {

thisx = x;

}

public float getY() {

return y;

}

public void setY(float y) {

thisy = y;

}

public Point nextPoint(Orien o) {

float tempX = x;

float tempY = y;

switch (o) {

case UP:

tempY = y - LINE_LENGTH;

break;

case DOWN:

tempY = y + LINE_LENGTH;

break;

case LEFT:

tempX = x - LINE_LENGTH;

break;

case RIGHT:

tempX = x + LINE_LENGTH;

break;

case UNKNOWN:

break;

}

return new Point(tempX, tempY);

}

}

enum Orien {

UP, LEFT, DOWN, RIGHT, UNKNOWN

}

public static class DrawThread extends Thread {

private List<Point> points = Collections

synchronizedList(new ArrayList<Point>());

private boolean mRun;

private Paint mPaint;

private Orien curOrien;

public synchronized void setRun(boolean run) {

thismRun = run;

notifyAll();

}

public synchronized boolean getRun() {

while (!mRun) {

try {

wait();

} catch (InterruptedException e) {

eprintStackTrace();

}

}

return mRun;

}

//当按上下左右键时,生成相应的点坐标

private synchronized boolean doKeyDown(int KeyCode, KeyEvent event) {

synchronized (holder) {

Point p = null;

switch (KeyCode) {

case KeyEventKEYCODE_DPAD_UP:

if (curOrien != OrienDOWN) {

curOrien = OrienUP;

p = curPointnextPoint(curOrien);

}

break;

case KeyEventKEYCODE_DPAD_DOWN:

if (curOrien != OrienUP) {

curOrien = OrienDOWN;

p = curPointnextPoint(curOrien);

}

break;

case KeyEventKEYCODE_DPAD_LEFT:

if (curOrien != OrienRIGHT) {

curOrien = OrienLEFT;

p = curPointnextPoint(curOrien);

}

break;

case KeyEventKEYCODE_DPAD_RIGHT:

if (curOrien != OrienLEFT) {

curOrien = OrienRIGHT;

p = curPointnextPoint(curOrien);

}

break;

default:

curOrien = OrienUNKNOWN;

}

if (p != null) {

curPoint = p;

pointsadd(p);

setRun(true);

}

Logi(LOG_TAG, curOrientoString());

}

return true;

}

//当释放按键时,停止绘图

private synchronized boolean doKeyUp(int KeyCode, KeyEvent event) {

synchronized (holder) {

setRun(false);

curOrien = OrienUNKNOWN;

}

return true;

}

SurfaceHolder holder;

private Point curPoint;

public DrawThread(SurfaceHolder holder) {

thisholder = holder;

mPaint = new Paint();

mPaintsetColor(ColorGREEN);

curPoint = new Point(50, 50);

pointsadd(curPoint);

}

public void resetPoint() {

}

private void doDraw(Canvas canvas) {

for (int i = 0; i + 1 < pointssize(); i += 1) {

Point lp = pointsget(i);

Point np = pointsget(i + 1);

canvasdrawLine(lpgetX(), lpgetY(), npgetX(), npgetY(),

mPaint);

}

}

@Override

public void run() {

Canvas canvas = null;

while (getRun()) {

try {

canvas = holderlockCanvas();

synchronized (holder) {

doDraw(canvas);

}

} finally {

holderunlockCanvasAndPost(canvas);

setRun(false);

}

}

}

}

private DrawThread thread;

public static final String LOG_TAG = "CanvasView";

private static final int LINE_LENGTH = 30;

public CanvasView(Context context) {

super(context);

}

public CanvasView(Context context, AttributeSet attrs) {

super(context, attrs);

//SurfaceView由SurfaceHolder管理

SurfaceHolder holder = getHolder();

holderaddCallback(this);

thread = new DrawThread(holder);

threadstart();

}

@Override

public boolean onKeyDown(int keyCode, KeyEvent event) {

return threaddoKeyDown(keyCode, event);

}

@Override

public boolean onKeyUp(int keyCode, KeyEvent event) {

return threaddoKeyUp(keyCode, event);

}

@Override

public void surfaceChanged(SurfaceHolder holder, int format, int width,

int height) {

Logi(LOG_TAG, "surfaceChanged");

threadresetPoint();

threadsetRun(true);

}

@Override

public void surfaceCreated(SurfaceHolder holder) {

Logi(LOG_TAG, "surfaceCreated");

threadresetPoint();

threadsetRun(true);

}

@Override

public void surfaceDestroyed(SurfaceHolder holder) {

Logi(LOG_TAG, "surfaceDestroyed");

threadsetRun(false);

}

}

:应该是切到其他界面时surfaceview就执行了onSurfaceDestory方法 但是你的线程还在调用surfaceview里的东西,所以出错了。最好把surfaceView的代码也贴出来

以上就是关于如何使用surfaceview全部的内容,包括:如何使用surfaceview、android surfaceview怎么留住最后一帧、等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/9377999.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-27
下一篇2023-04-27

发表评论

登录后才能评论

评论列表(0条)

    保存