Android SurfaceView每次触摸生成新圆并保留历史圆的实现问题
SurfaceView 多圆形保留绘制解决方案
问题原因
- 原有代码每次渲染循环都会调用
canvas.drawARGB(255,255,255,255)清空画布,之前绘制的圆形会被直接覆盖 - 仅存储了最后一次触摸的坐标,没有维护所有历史圆形的坐标、颜色等属性
- 未给当前View绑定触摸监听器,
onTouch回调默认不会触发 - 画笔颜色仅在初始化时生成一次,无法实现每个圆形随机颜色的需求
修改后完整代码
import android.graphics.Canvas; import android.graphics.Paint; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import java.util.ArrayList; import java.util.List; import java.util.Random; public class ArtSurface extends SurfaceView implements Runnable, View.OnTouchListener { private SurfaceHolder aHolder; private Thread aThread; private boolean aFlag = false; private Paint aPaint; private Random cRandom; // 存储所有历史圆形的列表 private List<Circle> circleList = new ArrayList<>(); // 圆形属性实体类 private static class Circle { float x; float y; int color; float radius = 50; public Circle(float x, float y, int color) { this.x = x; this.y = y; this.color = color; } } public int randomColor(){ if (cRandom == null){ cRandom = new Random(); } int randomCol = 0xff000000 + 256 * 256 * cRandom.nextInt(256) + 256 * cRandom.nextInt(256) + cRandom.nextInt(256); return randomCol; } public ArtSurface(Context context, AttributeSet attrs) { super(context, attrs); aHolder = getHolder(); aPaint = new Paint(); // 绑定触摸监听 setOnTouchListener(this); } public void resume(){ aThread = new Thread(this); aFlag = true; aThread.start(); } public void pause(){ aFlag = false; } @Override public boolean onTouch(View view, MotionEvent motionEvent) { switch(motionEvent.getAction()){ case MotionEvent.ACTION_DOWN: // 每次触摸新增一个随机颜色的圆形存入列表 circleList.add(new Circle(motionEvent.getX(), motionEvent.getY(), randomColor())); break; case MotionEvent.ACTION_UP: break; } return true; } @Override public void run() { while(aFlag){ if(!aHolder.getSurface().isValid()) continue; Canvas canvas = aHolder.lockCanvas(); // 清屏 canvas.drawARGB(255,255,255,255); // 遍历绘制所有历史圆形 for (Circle circle : circleList) { aPaint.setColor(circle.color); canvas.drawCircle(circle.x, circle.y, circle.radius, aPaint); } aHolder.unlockCanvasAndPost(canvas); // 加16ms延时控制帧率在60左右,降低CPU占用 try { Thread.sleep(16); } catch (InterruptedException e) { e.printStackTrace(); } } } }
内容的提问来源于stack exchange,提问作者Muiruri
相关产品推荐
相关产品推荐

