Skip to content

Instantly share code, notes, and snippets.

@ok3141
Created July 15, 2015 11:18
Show Gist options
  • Save ok3141/891c69ef6333a505f3f1 to your computer and use it in GitHub Desktop.
Save ok3141/891c69ef6333a505f3f1 to your computer and use it in GitHub Desktop.
How to use SurfaceView
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Canvas;
import android.os.Build;
import android.util.AttributeSet;
import android.view.SurfaceView;
public class SurfaceViewExt extends SurfaceView implements SurfaceViewHelper.Client {
private SurfaceViewHelper mHelper;
public SurfaceViewExt(Context context) {
super(context);
}
public SurfaceViewExt(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SurfaceViewExt(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public SurfaceViewExt(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
getHolder().addCallback(mHelper = new SurfaceViewHelper(this));
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
getHolder().removeCallback(mHelper);
mHelper = null;
}
public void postRepaint() {
if (mHelper != null) {
mHelper.postRepaint();
}
}
public void onSurfaceCreated() {
// for inheritors
}
public void onSurfaceChanged(int format, int width, int height) {
// for inheritors
}
public void onSurfaceDestroyed() {
// for inheritors
}
public void onRepaint(Canvas c) {
// for inheritors
}
}
import android.graphics.Canvas;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.view.SurfaceHolder;
import java.util.concurrent.atomic.AtomicInteger;
public class SurfaceViewHelper implements SurfaceHolder.Callback, Handler.Callback {
private static final AtomicInteger sCounter = new AtomicInteger();
private static final int WHAT_REPAINT = 0;
private static final int WHAT_SURFACE_CREATED = 1;
private static final int WHAT_SURFACE_CHANGED = 2;
private static final int WHAT_SURFACE_DESTROYED = 3;
private final Client mClient;
private HandlerThread mThread;
private Handler mHandler;
public SurfaceViewHelper(Client client) {
mClient = client;
}
public void postRepaint() {
if (mHandler != null) {
mHandler.sendEmptyMessage(WHAT_REPAINT);
}
}
@Override
public synchronized void surfaceCreated(SurfaceHolder holder) {
mThread = new HandlerThread(SurfaceViewExt.class.getSimpleName() + "-" + sCounter.incrementAndGet());
mThread.start();
mHandler = new Handler(mThread.getLooper(), this);
mHandler.sendEmptyMessage(WHAT_SURFACE_CREATED);
}
@Override
public synchronized void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Message.obtain(mHandler, WHAT_SURFACE_CHANGED, width, height, format).sendToTarget();
}
@Override
public synchronized void surfaceDestroyed(SurfaceHolder holder) {
mHandler.removeMessages(WHAT_REPAINT);
mHandler.sendEmptyMessage(WHAT_SURFACE_DESTROYED);
}
@Override
public synchronized boolean handleMessage(Message msg) {
switch (msg.what) {
case WHAT_REPAINT:
mHandler.removeMessages(WHAT_REPAINT);
performRepaint();
break;
case WHAT_SURFACE_CREATED:
mClient.onSurfaceCreated();
break;
case WHAT_SURFACE_CHANGED:
mClient.onSurfaceChanged((Integer) msg.obj, msg.arg1, msg.arg2);
break;
case WHAT_SURFACE_DESTROYED:
mClient.onSurfaceDestroyed();
mHandler.removeMessages(WHAT_REPAINT);
mHandler = null;
mThread.quit();
break;
}
return true;
}
private void performRepaint() {
Canvas canvas = mClient.getHolder().lockCanvas();
if (canvas != null) {
mClient.onRepaint(canvas);
mClient.getHolder().unlockCanvasAndPost(canvas);
}
}
public interface Client {
SurfaceHolder getHolder();
void onSurfaceCreated();
void onSurfaceChanged(int format, int width, int height);
void onSurfaceDestroyed();
void onRepaint(Canvas c);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment