使用多路径和绘制对象时,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。维米诺夫帮助我解决了我的问题。我想我已经见过这种实现,但在我的例子中,我不想使用位图。无论如何,谢谢你提供的样本,我回家后会仔细看看:-)我是如何做到的?我是如何做到的?谢谢你提供的例子。但实际上,我需要将所有笔划存储为路径,而不仅仅是在画布上绘制触感。谢谢您提供的示例。但实际上,我需要将所有笔划存储为路径,而不仅仅是在画布上绘制触摸。