使用SurfaceView关键在于下面的3个回调方法。
当(SurfaceHolder.addCallback()成功时调用public void surfaceCreated(SurfaceHolder holder);
当SurfaceView的状态发生变化时调用public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) ;
当SurfaceView被销毁时调用public void surfaceDestroyed(SurfaceHolder holder) ;
1、xml文件如下,SurfaceView控件的使用,有2两种方法,一种是在xml中定义id,并在Activity中初始化(例如本文),另一种是自定义SurfaceView控件,在xml文件中之间引入类文件。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SurfaceViewActivity">
<ImageView
android:id="@+id/sfv_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@mipmap/henu"/>
<SurfaceView
android:id="@+id/sfv"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<LinearLayout
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal">
<Button
android:id="@+id/stop"
android:gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:text="停止"/>
<Button
android:id="@+id/start"
android:gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:text="开始"/>
</LinearLayout>
</RelativeLayout>
2、SurfaceViewActivity.java文件
package ltd.ruiaixinan.test;
import android.graphics.PixelFormat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class SurfaceViewActivity extends AppCompatActivity {
private SurfaceView surfaceView = null;
private Button start = null;
private Button stop = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_surface_view);
this.surfaceView = this.findViewById(R.id.sfv);
this.start = this.findViewById(R.id.start);
this.stop = this.findViewById(R.id.stop);
// 设置常亮
this.surfaceView.setKeepScreenOn(true);
// 设置surfaceView背景透明
this.surfaceView.setZOrderOnTop(true);
this.surfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
// 调用SurfaceView
final SurfaceViewModel model = new SurfaceViewModel(this, this.surfaceView);
this.start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(SurfaceViewActivity.this,"开始绘画", Toast.LENGTH_SHORT).show();
model.start();
}
});
this.stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(SurfaceViewActivity.this,"停止绘画", Toast.LENGTH_SHORT).show();
model.stop();
}
});
}
}
3、SurfaceViewModel.java文件
package ltd.ruiaixinan.test;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class SurfaceViewModel extends SurfaceView implements SurfaceHolder.Callback, Runnable {
private Canvas canvas = null;
private Paint paint = null;
private SurfaceHolder surfaceHolder = null;
private int refreshInterval = 2000;
private volatile boolean isDrawing = false;
private Thread thread = null;
public SurfaceViewModel(Context context, SurfaceView surfaceView) {
super(context);
// 初始化画笔
this.paint = new Paint(Paint.ANTI_ALIAS_FLAG);
this.paint.setColor(Color.RED);
this.paint.setStrokeWidth(6);
this.surfaceHolder = surfaceView.getHolder();
// 触发回调函数
this.surfaceHolder.addCallback(this);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
Log.d("----------", "surfaceCreated success");
this.canvas = this.surfaceHolder.lockCanvas();
// 清空canvas
this.canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
this.surfaceHolder.unlockCanvasAndPost(this.canvas);
// 调用线程,对应下文相应的run()方法
this.thread = new Thread(this);
thread.start();
// 设置绘图中
this.isDrawing = true;
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Log.d("----------", "surfaceChanged success");
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.d("----------", "surfaceDestroyed success");
}
@Override
public void run() {
try {
while (true) {
if(this.isDrawing) {
Log.d("***", "run");
// Start time
long startTime = System.currentTimeMillis();
// The lock of thread
synchronized (this.surfaceHolder) {
this.canvas = this.surfaceHolder.lockCanvas();
// 设置canvas透明度
this.canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
Log.d("-------", "drawECG_good_start");
this.drawECG((int) (1 + Math.random() * 400));
Log.d("-------", "drawECG_good_end");
this.surfaceHolder.unlockCanvasAndPost(this.canvas);
}
// 设置结束时间
long endTime = System.currentTimeMillis();
// 计算间期
int intervalTime = (int) (endTime - startTime);
// 确保间期相同
while (intervalTime <= this.refreshInterval) {
intervalTime = (int) (System.currentTimeMillis() - startTime);
// Thread wait
Thread.yield();
}
}else {
Thread.yield();
}
}
}finally {
if(this.canvas != null){
// 解锁
this.surfaceHolder.unlockCanvasAndPost(this.canvas);
}
}
}
// Draw
private boolean drawECG(int x){
this.canvas.drawLine(x+10,x+10,x+100,x+100,this.paint);
return true;
}
// 启动绘画
public boolean start(){
this.isDrawing = true;
return true;
}
// 停止绘画
public boolean stop(){
Log.d("***","stop");
this.isDrawing = false;
return true;
}
}