从ArrayList绘制路径不起作用

时间:2013-04-28 10:00:01

标签: android

当我在屏幕上移动手指时,当我试图绘制路径时,我的应用程序强制关闭。代码开始绘制路径中的一些行,但随后强制关闭。我做错了什么?

MainActivity类中的OnTouchListener:

    @Override
public boolean onTouch(View v, MotionEvent event) {

    switch (event.getAction()) {

    case MotionEvent.ACTION_DOWN:
        gameLoop.touchDownX = event.getX();
        gameLoop.touchDownY = event.getY();
        break;

    case MotionEvent.ACTION_MOVE:
        Point point = new Point();
        point.x = (int) event.getX();
        point.y = (int) event.getY();
        gameLoop.addPoints(point);
        gameLoop.startDrawLine = true;
        break;

    case MotionEvent.ACTION_UP:
        gameLoop.touchUpX = event.getX();
        gameLoop.touchUpY = event.getY();
        gameLoop.touchActionUp = true;
        break;
    }

    return true; 
}

GameLoop类中的draw方法:

    // Method to draw objects
private void drawObjects(Canvas canvas) {

    // Clear screen with black color
    canvas.drawRGB(0, 0, 0);

    // Draw line
    if(startDrawLine) {

        // Set properties to Paint object
        paint.setColor(Color.WHITE);
        paint.setStrokeWidth(5);
        paint.setStyle(Paint.Style.STROKE);
        paint.setAntiAlias(true);

        // Draw path
        path.moveTo(touchDownX, touchDownY);

        for(Point point: points) {
            path.lineTo(point.x, point.y);
            canvas.drawPath(path, paint);
        }
        path.reset();
    }

LogCat信息:

04-28 11:54:23.155: W/dalvikvm(2896): threadid=10: thread exiting with uncaught  exception (group=0x40018578)
04-28 11:54:23.155: E/AndroidRuntime(2896): FATAL EXCEPTION: Thread-11
04-28 11:54:23.155: E/AndroidRuntime(2896): java.util.ConcurrentModificationException
04-28 11:54:23.155: E/AndroidRuntime(2896):     at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:576)
04-28 11:54:23.155: E/AndroidRuntime(2896):     at com.androidTest.mergemania.GameLoop.drawObjects(GameLoop.java:251)
04-28 11:54:23.155: E/AndroidRuntime(2896):     at com.androidTest.mergemania.GameLoop.run(GameLoop.java:216)
04-28 11:54:23.155: E/AndroidRuntime(2896):     at java.lang.Thread.run(Thread.java:1019)

1 个答案:

答案 0 :(得分:1)

是drawObjects中的所有代码吗? LogCat告诉我们您在迭代时修改列表。我希望你有这样的代码打破:

    for(Point point: points) {
        path.lineTo(point.x, point.y);
        canvas.drawPath(path, paint);
        points.remove(point); // this line added
    }

修改

哦,你可能正在使用SurfaceView并在一个单独的线程中绘图。在这种情况下,您需要将调用与点列表同步。也许使用CopyOnWriteArrayList

请阅读SurfaceView上的线索。

<强> EDIT2:

这样的东西应该可行,但我真的不会在生产代码中使用它,因为它会阻塞线程。您需要拥有非常少量的代码(就执行时间而言)才能使线程高效工作。 (添加了4行,注释了this line added)。

@Override
public boolean onTouch(View v, MotionEvent event) {

synchronized (gameLoop) { // this line added

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:
    gameLoop.touchDownX = event.getX();
    gameLoop.touchDownY = event.getY();
    break;

case MotionEvent.ACTION_MOVE:
    Point point = new Point();
    point.x = (int) event.getX();
    point.y = (int) event.getY();
    gameLoop.addPoints(point);
    gameLoop.startDrawLine = true;
    break;

case MotionEvent.ACTION_UP:
    gameLoop.touchUpX = event.getX();
    gameLoop.touchUpY = event.getY();
    gameLoop.touchActionUp = true;
    break;
}

} // this line added

return true; 
}

和此:

// Method to draw objects
private void drawObjects(Canvas canvas) {

synchronized (this) { // this line added

// Clear screen with black color
canvas.drawRGB(0, 0, 0);

// Draw line
if(startDrawLine) {

    // Set properties to Paint object
    paint.setColor(Color.WHITE);
    paint.setStrokeWidth(5);
    paint.setStyle(Paint.Style.STROKE);
    paint.setAntiAlias(true);

    // Draw path
    path.moveTo(touchDownX, touchDownY);

    for(Point point: points) {
        path.lineTo(point.x, point.y);
        canvas.drawPath(path, paint);
    }
    path.reset();
}

} // this line added