本篇文章讲在自定义surfaceView画图中遇到的几个问题
- 1.surfaceView,OnTouch方法中 ACTION_MOVE和ACTION_UP不执行
在写自定义surfaceView发现,不管是在onTouchEvent 还是 OnTouchListener中,都只执行ACTION_DOWN。
最后发现,需要在XML中加上 android:clickable=”true”
- 2.surfaceView在重复画图屏幕一直闪烁
这里需要在每次画图前加上 canvas.drawColor(Color.BLACK);
canvas=mSurfaceHolder.lockCanvas();
if(canvas!=null){
Paint paint = new Paint();
canvas.drawColor(Color.BLACK);
canvas.drawRect(startX,startY,toX,toY,mPaint);
//提交显示视图并解锁,防止长期占用此内存
mSurfaceHolder.unlockCanvasAndPost(canvas);
}
- 3.背景颜色透明,并且重复绘制不用drawColor黑背景
canvas.drawColor(Color.BLACK)虽然可以防止屏幕闪烁,但是背景每次都要从新绘黑背景,导致不能看到surfaceView下面的控件。
这就需要把surfaceView背景颜色设置透明,并且在每次绘制时不能绘制黑背景。
if(canvas!=null){
//清屏操作或者设置背景
Paint paint = new Paint();
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.drawPaint(paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
canvas.drawRect(startX,startY,toX,toY,mPaint);
//提交显示视图并解锁,防止长期占用此内存
mSurfaceHolder.unlockCanvasAndPost(canvas);
}
整个类代码如下:
/**
* Created by mac on 17-2-27.
* 自定义控件
*/
public class TestSurfaceView extends SurfaceView implements SurfaceHolder.Callback,View.OnTouchListener{
private SurfaceHolder mSurfaceHolder;
private float startX,startY,toX,toY;
Canvas canvas = null;
private Paint mPaint;
public TestSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return super.onTouchEvent(event);
}
public TestSurfaceView(Context context) {
super(context);
init();
}
private void init(){
mSurfaceHolder=this.getHolder();
mSurfaceHolder.addCallback(this);
this.setZOrderOnTop(true);
mSurfaceHolder.setFormat(PixelFormat.TRANSLUCENT);
}
private void draw() {
mPaint = new Paint();
mPaint.reset();
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(3);
mPaint.setColor(Color.YELLOW);
//连接处更加平滑
mPaint.setStrokeJoin(Paint.Join.ROUND);
canvas=mSurfaceHolder.lockCanvas();
if(canvas!=null){
//清屏操作或者设置背景
Paint paint = new Paint();
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.drawPaint(paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
canvas.drawRect(startX,startY,toX,toY,mPaint);
//提交显示视图并解锁,防止长期占用此内存
mSurfaceHolder.unlockCanvasAndPost(canvas);
}
}
private void upDraw(){
mPaint = new Paint();
mPaint.reset();
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mPaint.setStrokeWidth(3);
mPaint.setColor(Color.YELLOW);
//连接处更加平滑
mPaint.setStrokeJoin(Paint.Join.ROUND);
canvas=mSurfaceHolder.lockCanvas();
if(canvas!=null){
Paint paint = new Paint();
//清屏操作或者设置背景
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.drawPaint(paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
canvas.drawRect(startX,startY,toX,toY,mPaint);
//提交显示视图并解锁,防止长期占用此内存
mSurfaceHolder.unlockCanvasAndPost(canvas);
}
}
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.i("Test","onTouchEvent()");
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
startX = event.getX();
startY = event.getY();
Log.i("Test","ACTION_DOWN");
break;
case MotionEvent.ACTION_MOVE:
toX = event.getX();
toY = event.getY();
Log.i("Test","ACTION_MOVE");
draw();
break;
case MotionEvent.ACTION_UP:
toX = event.getX();
toY = event.getY();
Log.i("Test","ACTION_UP");
upDraw();
break;
}
return false;
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
setOnTouchListener(this);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
}