使用多路径和绘制对象时,Android画布会被清理
有人能解释一下为什么这段代码不能画出每一个物体吗使用多路径和绘制对象时,Android画布会被清理,android,canvas,path,ondraw,Android,Canvas,Path,Ondraw,有人能解释一下为什么这段代码不能画出每一个物体吗 public class A extends View { private Paint paint = new Paint(); private Path path = new Path(); ArrayList<Pair<Path, Paint>> paths = new ArrayList<Pair<Path, Paint>>(); public A(Context context) {
public class A extends View {
private Paint paint = new Paint();
private Path path = new Path();
ArrayList<Pair<Path, Paint>> paths = new ArrayList<Pair<Path, Paint>>();
public A(Context context) {
super(context);
}
@Override
protected void onDraw(Canvas canvas) {
for (Pair<Path, Paint> p : paths) {
canvas.drawPath(p.first, p.second);
}
canvas.drawPath(path, paint);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float eventX = event.getX();
float eventY = event.getY();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(3f);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
int color = Color.rgb(new Random().nextInt(255),
new Random().nextInt(255),
new Random().nextInt(255));
paint.setColor(color);
path.reset(); //new stroke, get old one erased
int historySize = event.getHistorySize();
for (int i = 0; i > historySize; i++) {
path.moveTo(eventX, eventY);
}
path.moveTo(eventX, eventY);
return true;
case MotionEvent.ACTION_MOVE:
path.lineTo(eventX, eventY);
return true;
case MotionEvent.ACTION_UP:
path.lineTo(eventX, eventY);
// End of stroke, add this to the collection
paths.add(new Pair<Path, Paint>(path, paint));
break;
default:
break;
}
// Schedules a repaint.
invalidate();
return true;
}
公共A类扩展视图{
私人油漆=新油漆();
私有路径路径=新路径();
ArrayList路径=新的ArrayList();
公共A(上下文){
超级(上下文);
}
@凌驾
受保护的void onDraw(画布){
用于(对p:路径){
画布绘制路径(第一页,第二页);
}
画布.绘制路径(路径,绘制);
}
@凌驾
公共布尔onTouchEvent(运动事件){
float eventX=event.getX();
float eventY=event.getY();
paint.setAntiAlias(真);
绘制.设置样式(绘制.样式.笔划);
绘制.设置行程连接(绘制.连接.圆形);
油漆。设置行程宽度(3f);
开关(event.getAction()){
case MotionEvent.ACTION\u DOWN:
int color=color.rgb(new Random().nextInt(255),
new Random().nextInt(255),
new Random().nextInt(255));
油漆。设置颜色(颜色);
path.reset();//新笔划,删除旧笔划
int historySize=event.getHistorySize();
对于(int i=0;i>historySize;i++){
path.moveTo(eventX,eventY);
}
path.moveTo(eventX,eventY);
返回true;
case MotionEvent.ACTION\u移动:
lineTo(eventX,eventY);
返回true;
case MotionEvent.ACTION\u UP:
lineTo(eventX,eventY);
//笔划结束时,将其添加到集合中
添加(新对(路径,绘制));
打破
违约:
打破
}
//安排重画。
使无效();
返回true;
}
}
我用onTouchEvent捕捉每一个笔划,并创建不同的路径/绘制对象,存储在一对中。可悲的是,在我的画作中,当我试图把它们全部画出来时,却失败了。。
我读过一些题目,但没有找到正确的答案。每次都有人建议创建和使用位图并将其绘制到屏幕上,但我希望避免使用这种解决方案
谢谢你的帮助 移除路径。在开关状态下重置。这幅画很有用。但即使是上一次绘制,颜色也会发生变化。重置正在清除上一个图形的路径 每次我都会用不同的一对(路径和绘画)来画画 如果你想用画布画,下面的代码就可以了。 我还将添加一个颜色选择器,允许用户选择自己选择的颜色
public class MyView extends View {
private static final float MINP = 0.25f;
private static final float MAXP = 0.75f;
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
public MyView(Context c) {
super(c);
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(0xFFAAAAAA);
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
canvas.drawPath(mPath, mPaint);
}
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
private void touch_start(float x, float y) {
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
}
private void touch_move(float x, float y) {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
mX = x;
mY = y;
}
}
private void touch_up() {
mPath.lineTo(mX, mY);
// commit the path to our offscreen
mCanvas.drawPath(mPath, mPaint);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SCREEN));
// kill this so we don't double draw
mPath.reset();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
invalidate();
break;
}
return true;
}
}
移除路径。在开关状态下重置。这幅画很有用。但即使是上一次绘制,颜色也会发生变化。重置正在清除上一个图形的路径 每次我都会用不同的一对(路径和绘画)来画画 如果你想用画布画,下面的代码就可以了。 我还将添加一个颜色选择器,允许用户选择自己选择的颜色
public class MyView extends View {
private static final float MINP = 0.25f;
private static final float MAXP = 0.75f;
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
public MyView(Context c) {
super(c);
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(0xFFAAAAAA);
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
canvas.drawPath(mPath, mPaint);
}
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
private void touch_start(float x, float y) {
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
}
private void touch_move(float x, float y) {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
mX = x;
mY = y;
}
}
private void touch_up() {
mPath.lineTo(mX, mY);
// commit the path to our offscreen
mCanvas.drawPath(mPath, mPaint);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SCREEN));
// kill this so we don't double draw
mPath.reset();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
invalidate();
break;
}
return true;
}
}
问题是您总是使用相同的
路径
和绘制
对象。每次MotionEvent时,您应该创建新的路径
和绘制
。动作
被触发问题是您总是使用相同的路径
和绘制
对象。每次MotionEvent时,您都应该创建新的路径
和绘制
。触发动作
,您只需要使用一个路径和绘制对象
关于这整件事的详细教程实际上可以在这里找到:
您只需要使用一个路径和绘制对象 关于这整件事的详细教程实际上可以在这里找到:
问题是您总是使用相同的
路径
和绘制
对象。当MotionEvent.ACTION\u DOWN
被触发时,你应该创建新的Path
和Paint
。vmironov,你是我的英雄!我在这个问题上已经被困了将近两天了!我加了油漆=新的痛苦();和路径=新路径();在MotionEvent.ACTION\u上按下,现在它可以工作了。我认为所有的东西都是用java复制的,而不是引用的,所以我认为我的两个对象每次都是不同的。。。非常感谢。你能让它工作真是太好了!我已经发布了我的评论作为答案,所以您可以使用它。问题是您总是使用相同的路径
和绘制
对象。当MotionEvent.ACTION\u DOWN
被触发时,你应该创建新的Path
和Paint
。vmironov,你是我的英雄!我在这个问题上已经被困了将近两天了!我加了油漆=新的痛苦();和路径=新路径();在MotionEvent.ACTION\u上按下,现在它可以工作了。我认为所有的东西都是用java复制的,而不是引用的,所以我认为我的两个对象每次都是不同的。。。非常感谢。你能让它工作真是太好了!我已经发布了我的评论作为回答,所以你可以这样做。谢谢@Raghunandan。维米诺夫帮助我解决了我的问题。我想我已经见过这种实现,但在我的例子中,我不想使用位图。无论如何,谢谢你提供的样品,我回家后会仔细看看:-)谢谢你@Raghunandan。维米诺夫帮助我解决了我的问题。我想我已经见过这种实现,但在我的例子中,我不想使用位图。无论如何,谢谢你提供的样本,我回家后会仔细看看:-)我是如何做到的?我是如何做到的?谢谢你提供的例子。但实际上,我需要将所有笔划存储为路径,而不仅仅是在画布上绘制触感。谢谢您提供的示例。但实际上,我需要将所有笔划存储为路径,而不仅仅是在画布上绘制触摸。