0

Android プロジェクトで冗長なコードを削減しようとしています。私がすでに持っているものをお話ししましょう。

2 つの主要なビュー グループがあります。1 つは MapView と呼ばれ、ズームやパンなどを行うことができるビットマップを含むビューです。もう 1 つは StepInfoView と呼ばれ、座標の配列やそれらの座標に関する情報などの静的データを含むビューです。このビューも、MapView と同じ方法でズームおよびパンされますが、スケール ファクターとパンされる量は、MapView から独立している必要があります。

StepInfoView はいくつかの異なるクラス (合計 6 つ) によって拡張されており、それらはすべて同期する必要があります (座標は 1 つにプロットされ、座標間の線は別のクラスにプロットされるなど)。

したがって、現在、私のコードの要点は次のとおりです。

public class MapView extends View
{
    protected float scale = 1;

    protected class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener
    {
        @Override
        public boolean onScale(ScaleGestureDetector detector)
        {
            scale *= detector.getScaleFactor());
            return true;
        }

    }

    }
... 

public class StepInfoView extends View
{
    static protected float scale = 1;
    protected class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener
    {
        @Override
        public boolean onScale(ScaleGestureDetector detector)
        {
            scale *= detector.getScaleFactor());
            return true;
        }

    }
}
...
public class StepView extends StepInfoView
{  
    // Custom onDraw, same scale as PathView
}
public class PathView extends StepInfoView
{
    // Custom onDraw, same scale as StepView
}

ご覧のとおり、onScales は同一です。スケーリング関数を保持する抽象クラスを作成したいので、それを RootView と呼びましょう。MapView と StepInfoView の両方にスケールがありますが、MapView スケールは StepInfoView から独立している必要があるため、RootView でスケールを静的にすることはできません。これがうまくいくとわかっている解決策ですが、ゲッターとセッターの混乱は好きではありません。

abstract class RootView extends View
{
    abstract protected float getScale();

    abstract protected void setScale(float s);
    protected class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener
    {
        @Override
        public boolean onScale(ScaleGestureDetector detector)
        {
         setScale(getScale() * detector.getScaleFactor());
         return true;
        }
    }
}
...
public class MapView extends RootView
{
    public float scale = 1;
    protected float getScale(){
        return scale;
    }

    protected void setScale(float s){
        scale = s;
    }
}

public class StepInfoView extends RootView
{
    public static float scale = 1;
    protected float getScale(){
        return scale;
    }

    protected void setScale(float s){
        scale = s;
    }
}
public class StepView extends StepInfoView
{  
    // Custom onDraw, same scale as PathView
}
public class PathView extends StepInfoView
{
    // Custom onDraw, same scale as StepView
}

それはまさに私が望むように機能しますが、ここでも同じコードが重複しています (ゲッターとセッター、および MapView と StepInfoView の「スケール」変数)。

私ができることは、RootView で非静的スケールを宣言し、それを StepInfoView で静的として「キャスト」することです。それは正確には不可能です...

手伝ってもらえますか?

4

3 に答える 3

1

float のコストは約 4 バイトです。別のクラスを使用すると、これよりもかなり多くのメモリが使用されます。オブジェクトは通常 8 バイトにアラインされているため、オブジェクトを小さくすることさえできない場合があります。

複雑さを避けたい場合は、フィールドを非静的のままにします。

あなたが持っている可能性があります

class RootView {
    protected final float[] scale;

    RootView() {
        scale = new float[] { 1.0f };
    }

    protected RootView(float[] scale) {
        this.scale = scale;
    }

    public boolean onScale(ScaleGestureDetector detector) {
        scale[0] *= detector.getScaleFactor();
        return true;
    }
}

class StepInfoView extends RootView {
    static final float[] scale = { 1.0f };

    StepInfoView() {
        super(scale);
    }
于 2012-08-03T11:35:00.200 に答える
0

scale フィールドをリスナーに移動し、get と set を提供します。

ビューで、リスナーへの参照を保持して、スケールにアクセスできるようにします。

MapView の場合、ビュー インスタンスごとに異なるリスナーを登録して、縮尺が異なるようにします。

StepInfoView の場合、ビュー インスタンスごとに同じリスナーを登録して、同じスケールになるようにします。リスナーへの参照を静的フィールドに格納できます。

于 2012-08-03T11:37:05.333 に答える
0

scaleフィールドをRootViewクラスに移動しないのはなぜですか?

更新:ちょうどそれを手に入れました。集計の場所があると思います。stepinfoscale値のオブジェクト コンテナーを作成し、StepInfoView を通過します。

とにかく、ゲッターを使用するのが最も簡単な方法だと思います。

于 2012-08-03T11:34:49.983 に答える