2012-04-18 21 views
4

私は座標のArrayList(これはxとyの位置だけを含むカスタムクラスです)を描画するカスタムビューを持っています。 ArrayListに座標が追加されるにつれて、描画が著しく遅くなります。私は、このArrayListを描画するより効率的な方法があるかどうか疑問に思っていた。あるいは、(ArrayListが無効にする呼び出し間に1つのCoordinateを変更するだけなので)追加された座標を追加するだけでよい。任意の助けArrayListの効率的なonDraw

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

2

Slaytonの改善を除いて、ArrayListの代わりにHashSetを使用することも可能です。この方法では、重複座標を追加することはできません。私はあなたがこれをしているかどうかは分かりませんが、もしあなたがこのような改善をしていれば、反復は減少します。

これを行う場合は、あなたが知っているCoordinateクラスにequalsメソッドを実装する必要があります。または、Coordinateがxとyの位置だけを保持している場合は、Java Pointクラスを使用することもできます。

+0

提案していただきありがとうございます。私は間違いなくそれを調べます。 – jrubins

1

私のアプローチは、各onDrawでキャンバスをビットマップに描画したり、ImageViewの拡張を使用してbackgroundDrawableを使用したりすることです。クラスにフィールドを追加して最新の新しい座標を保持し、その後のonDrawsでビットマップを取得し、新しい座標のみを追加します。リセットするには、単にバックグラウンドビットマップを再度設定するか、現在のようにView.setBackgroundを使用します。私はこれをテストしていないし、いくつかの拡張機能を使用することができますが、うまくいけば、あなたは一度に1つの座標を追加するだけで、あなたにアイデアを与え、効率的になるでしょう。

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); 

    ... 
    ... 

} 
関連する問題