2012-04-18 22 views
4

高效的onDraw我有一个自定义视图在其上我画坐标的ArrayList(这只是含有x和y位置的自定义类)。随着越来越多的坐标被添加到ArrayList,图形明显变慢。我想知道是否有一个更有效的方法来绘制这个ArrayList,或者,如果我可以只添加一个添加的坐标(因为ArrayList只更改一个坐标之间的坐标之间无效)。的ArrayList

这里是代码中的相关部分:

public class CustomDraw extends View { 
// member variables 

public void updateLine() { 
    // grab new coordinates for each measure 

    if(measure1.isEmpty()) { 
     measure1.add(new Coordinate(0, 0)); 
    } else { 
     Coordinate last_coord = measure1.get(measure1.size() - 1); 

     // calculations for south, north, east, and west 

     if(south && east) { 
      measure1.add(new Coordinate(last_coord.x + 3, last_coord.y + 3)); 
     } else if(south && west) { 
      measure1.add(new Coordinate(last_coord.x - 3, last_coord.y + 3)); 
     } else if(north && east) { 
      measure1.add(new Coordinate(last_coord.x + 3, last_coord.y - 3)); 
     } else if(north && west) { 
      measure1.add(new Coordinate(last_coord.x - 3, last_coord.y - 3)); 
     } 
    } 

    if(draw) { 
     dh.sleep(10); 
    } 
} 


@Override 
public void onDraw(Canvas c) { 
    super.onDraw(c); 
    Paint p = new Paint(); 
    p.setStyle(Paint.Style.FILL); 

    p.setColor(Color.WHITE); 
    c.drawPaint(p); 
    p.setColor(Color.BLACK); 

    switch(mSelected) { 
    case Constants.MEASURE_1: 
     for(int i = 0; i < measure1.size(); i++) { 
      Coordinate coord = measure1.get(i); 
      Log.d("MAAV", "drawing coord.x, coord.y: " + (coord.x) + ", " + (coord.y)); 
      c.drawRect(coord.x, coord.y, coord.x + 3, coord.y + 3, p); 
     } 
     break; 
    } 

} 

class DrawHandler extends Handler { 

    @Override 
    public void handleMessage(Message msg) { 
     CustomDraw.this.updateLine(); 
     CustomDraw.this.invalidate(); 
    } 

    public void sleep(long delayMillis) { 
     this.removeMessages(0); 
     sendMessageDelayed(obtainMessage(0), delayMillis); 
    } 
} 
} 

感谢您的帮助!

回答

3

您声明coord循环的每个迭代。您不需要这样做,并且为对象分配内存可能很昂贵。移动到循环外部并简单地重用该对象。还可以尝试注释日志调用或仅登录每个第10项。

Coordinate coord; 
for(int i = 0; i < measure1.size(); i++) { 
    coord = measure1.get(i) 
    if (i%10==0) 
     Log.d("MAAV", "drawing coord.x, coord.y: " + (coord.x) + ", " + (coord.y)); 
    c.drawRect(coord.x, coord.y, coord.x + 3, coord.y + 3, p); 
} 

如果这些更新不足以提高性能,请考虑使用OpenGL ES进行绘制。

+0

感谢伟大的工作! – jrubins 2012-04-18 21:26:05

2

除了从提高斯雷顿建议也可能是可行的使用HashSet的,而不是一个ArrayList的。这样你将无法添加重复的坐标。我不知道你是否正在这样做,但如果你是这种改进会减少迭代。

如果你选择这样做,你将需要实现的equals方法您协调课程,我敢肯定,你知道。或者你也可以使用java Point类,如果你的坐标只有x和y的位置。

+0

感谢您的建议。我一定会考虑这一点。 – jrubins 2012-04-18 21:26:28

1

我的做法是制定你的画布位图(或者使用的ImageView的扩展和使用backgroundDrawable)上的每个的onDraw。添加一个字段到您的班级以保存最新的坐标,然后在随后的onDraws中,检索位图并仅添加新的坐标。要重置,只需再次设置背景位图(或者像现在一样使用View.setBackground)。我没有测试过它,它可以使用一些增强功能,但希望它能给你提供这个想法,并且如果像你说的那样,你一次只增加一个坐标,那么它将是超高效的。

public class CustomDraw extends View { 

public Bitmap backgroundBitmap; 
public Coordinate newCoordinate; 

... 
... 

@Override 
public void onDraw(Canvas c) { 

    // no super.onDraw as we are drawing everything 

    Canvas backgroundCanvas = new Canvas(backgroundBitmap); 

    ... 
    ... 

    // draw new co-ordinate to the background bitmap 
    if (newCoordinate != null){ 
     drawCoordinate(backgroundCanvas, newCoordinate); 
     newCoordinate = null; 
    } 

    // draw the background bitmap to the view's canvas 
    c.drawBitmap(backgroundBitmap, null, null); 

    ... 
    ... 

}