效果图:
首先,让我们简单了解surfaceview.
通过查找,我们不难发现SurfaceView继承自View,所以它本质也是一个View。
其实,SurfaceView也是一个自定义View.主要方法也没有多少。
我们需要写一个自定义View.
SurfaceHolder 回调的依附,相当于句柄,手柄,接口的拥有者,是操作处理的持有者。
我们要使用句柄的callback接口,实现三个方法:创建、改变、销毁。
public interface Callback {
void surfaceCreated(SurfaceHolder var1);
void surfaceChanged(SurfaceHolder var1, int var2, int var3, int var4);
void surfaceDestroyed(SurfaceHolder var1);
}
还有绘制时触摸时间,还有线程持续操作。
用画笔绘制在画布上绘制路径。
代码比较简单:
自定义View MSurfaceView.java
public class MSurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable {
/**
* 是否处于绘制状态
*/
private boolean mIsDrawing;
/**
* 帮助类
*/
private SurfaceHolder mHolder;
/**
* 画布
*/
private Canvas mCanvas;
/**
* 路径
*/
private Path mPath;
/**
* 画笔
*/
private Paint mPaint;
public MSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mPath.moveTo(x, y);
break;
case MotionEvent.ACTION_MOVE:
mPath.lineTo(x, y);
break;
case MotionEvent.ACTION_UP:
break;
default:
break;
}
return true;
}
private void initView() {
mHolder = getHolder();
mHolder.addCallback(this);
setFocusable(true);
setFocusableInTouchMode(true);
this.setKeepScreenOn(true);
if (mPath == null) {
mPath = new Path();
}
if (mPaint == null) {
mPaint = new Paint();
}
mPaint.setAntiAlias(true);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(10);
}
@Override
public void run() {
long start = System.currentTimeMillis();
while (mIsDrawing) {
draw();
}
long end = System.currentTimeMillis();
if (end - start < 100) {
try {
Thread.sleep(100 - (end - start));
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
}
@Override
public void surfaceCreated(SurfaceHolder arg0) {
mIsDrawing = true;
new Thread(this).start();
}
@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
mIsDrawing = false;
}
private void draw() {
try {
mCanvas = mHolder.lockCanvas();
mCanvas.drawColor(Color.WHITE);
mCanvas.drawPath(mPath, mPaint);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (mCanvas != null) {
mHolder.unlockCanvasAndPost(mCanvas);
}
}
}
/**
* 清除内容
*/
public void reset() {
mPath.reset();
}
/**
* 设置字号颜色
* @param size
* @param color
*/
public void setLineSizeandColor(int size, int color) {
mPaint.setStrokeWidth(size);
mPaint.setColor(color);
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
MSurfaceView mSurfaceView;
LinearLayout winpop;
TextView setSize, reset;
RadioGroup group;
RadioButton size_ten, size_twelve, size_fifteen;
FrameLayout activity_main;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportActionBar().hide();
activity_main = (FrameLayout) findViewById(R.id.activity_main);
reset = (TextView) findViewById(R.id.reset);
setSize = (TextView) findViewById(R.id.setsize);
mSurfaceView = (MSurfaceView) findViewById(R.id.surfaceview);
winpop = (LinearLayout) findViewById(R.id.winpop);
activity_main.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (winpop.getVisibility() == View.VISIBLE) {
winpop.setVisibility(View.GONE);
}
}
});
reset.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mSurfaceView.reset();
if (winpop.getVisibility() == View.VISIBLE) {
winpop.setVisibility(View.GONE);
}
}
});
setSize.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
winpop.setVisibility(View.VISIBLE);
}
});
//根据ID找到RadioGroup实例
group = (RadioGroup) this.findViewById(R.id.radioGroup);
size_ten = (RadioButton) findViewById(R.id.sizeten);
size_twelve = (RadioButton) findViewById(R.id.sizetwelve);
size_fifteen = (RadioButton) findViewById(R.id.sizefifteen);
size_ten.setChecked(true);
//绑定一个匿名监听器
group.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup arg0, int arg1) {
// TODO Auto-generated method stub
int size, color;
if (arg1 == size_ten.getId()) {
size = 10;
color = Color.BLACK;
} else if (arg1 == size_twelve.getId()) {
size = 12;
color = Color.BLUE;
} else {
size = 15;
color = Color.RED;
}
mSurfaceView.setLineSizeandColor(size, color);
winpop.setVisibility(View.GONE);
}
});
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!--第一层-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="60dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:textColor="#642100"
android:textSize="18dp"
android:gravity="center"
android:text="画板使用" />
<TextView
android:id="@+id/setsize"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_marginRight="10dp"
android:clickable="true"
android:gravity="center"
android:textColor="#642100"
android:text="设置字号/颜色" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_alignParentBottom="true"
android:background="#dedede" />
</RelativeLayout>
<com.lcl.view.MSurfaceView
android:id="@+id/surfaceview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="60dp">
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_alignParentTop="true"
android:background="#dedede" />
<TextView
android:id="@+id/reset"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:textColor="#642100"
android:gravity="center"
android:text="重绘" />
</RelativeLayout>
</LinearLayout>
<!--第二层-->
<LinearLayout
android:id="@+id/winpop"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:visibility="gone">
<RadioGroup
android:id="@+id/radioGroup"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_gravity="right|top"
android:layout_marginTop="60dp"
android:background="#cdcdcd">
<RadioButton
android:id="@+id/sizeten"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="10号|黑色" />
<RadioButton
android:id="@+id/sizetwelve"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="12号|蓝色" />
<RadioButton
android:id="@+id/sizefifteen"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="15号|红色" />
</RadioGroup>
</LinearLayout>
</FrameLayout>