5

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

関連するコードは次のとおりです。

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

助けてくれてありがとう!

4

3 に答える 3

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 を使用して描画を行うことを検討してください。

于 2012-04-18T21:02:46.903 に答える
2

slayton が提案した改善を除いて、ArrayList の代わりに HashSet を使用することも実行可能である可能性があります。この方法では、重複した座標を追加することはできません。あなたがこれを行っているかどうかはわかりませんが、そうしている場合、この改善により反復が減少します。

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

于 2012-04-18T21:13:32.677 に答える
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);

    ...
    ...

}
于 2012-04-18T21:46:34.860 に答える