0

私はAndroidSurfaceViewクラスにもう少し慣れようとしています。そうすることで、ユーザーが画面内を移動できる簡単なアプリケーションを作成しようとしてBitmapいます。この実装の厄介な部分は、配置後にユーザーが画像を再度ドラッグできる機能も含まれていることです。これを行うために、ビットマップを、Bitmapの現在の位置を定義する単純な座標のセットにマッピングしています。ただし、画像をマッピングしている領域が画像と一致していません。

問題

SurfaceViewを使用して画像を配置しcanvas.drawBitmap()、配置された画像の座標を記録した後、私が設定したマッピングシステムは、Bitmapの座標を何らかの形で誤って解釈し、正しく表示されません。この画像でわかるように、私は単にcanvas.drawLine()タッチ領域のスペースを表す線を描画するために使用しました。画像は常にオフで右にあります。

.pngとテクスチャ領域は常にオフになっています!

コード

ここでは、私の質問に答えるのに役立つ関連コードの抜粋を提供します。

CustomSurface.java

このメソッドは、オブジェクトの描画をキャンバスにカプセル化します。コメントは各要素を明確にします:

public void onDraw(Canvas c){

    //Simple black paint
    Paint paint = new Paint();

    //Draw a white background
    c.drawColor(Color.WHITE);

    //Draw the bitmap at the coordinates
    c.drawBitmap(g.getResource(), g.getCenterX(), g.getCenterY(), null);

    //Draws the actual surface that is receiving touch input
    c.drawLine(g.left, g.top, g.right, g.top, paint);
    c.drawLine(g.right, g.top, g.right, g.bottom, paint);
    c.drawLine(g.right, g.bottom, g.left, g.bottom, paint);
    c.drawLine(g.left, g.bottom, g.left, g.top, paint);
}

このメソッドは、タッチイベントをキャプチャする方法をカプセル化します。

public boolean onTouchEvent(MotionEvent e){

    switch(e.getAction()){

        case MotionEvent.ACTION_DOWN:{

            if(g.contains((int) e.getX(), (int) e.getY()))
                item_selected = true;
            break;
        }
        case MotionEvent.ACTION_MOVE:{

            if(item_selected)      
                g.move((int) e.getX(), (int) e.getY());

            break;
        }
        case MotionEvent.ACTION_UP:{

            item_selected = false;
            break;
        }
        default:{

            //Do nothing
            break;
        }
    }

    return true;
}

Graphic.java

このメソッドは、グラフィックを作成するために使用されます。

//Initializes the graphic assuming the coordinate is in the upper left corner
public Graphic(Bitmap image, int start_x, int start_y){

    resource = image;
    left = start_x;
    top = start_y;
    right = start_x + image.getWidth();
    bottom = start_y + image.getHeight();
}

このメソッドは、ユーザーが画像内をクリックしているかどうかを検出します。

public boolean contains(int x, int y){

    if(x >= left && x <= right){

        if(y >= top && y <= bottom){

            return true;
        }
    }

    return false;
}

このメソッドは、グラフィックを移動するために使用されます。

public void move(int x, int y){

    left = x;
    top = y;
    right = x + resource.getWidth();
    bottom = y + resource.getHeight();
}

領域の中心を決定する2つの方法もあります(再描画に使用されます)。

public int getCenterX(){

    return (right - left) / 2 + left;
}

public int getCenterY(){

    return (bottom - top) / 2 + top;
}

他の多くのStackOverflowユーザーがこの問題の解決策から本当に恩恵を受けることができるように私は感じています。

4

2 に答える 2

1

Android Developers ブログに、タッチ/マルチタッチ/ジェスチャの非常に優れた完全な説明があり、google code にある無料のオープン ソース コードの例が含まれています。

どうぞ、ご覧ください。ジェスチャーが必要ない場合は、その部分をスキップして、タッチ イベントについてのみ読んでください。

于 2012-11-14T01:50:09.113 に答える
0

この問題は私が思っていたよりもはるかに単純であり、いくつかの微調整の後、これが画像幅の補正の問題であることに気付きました。

上記のコードの次の行で、エラーが発生します。

c.drawBitmap(g.getResource(), g.getCenterX(), g.getCenterY(), null);

おわかりのように、クラス内から座標を操作してビットマップの中心を生成し、中心から外側に描画すると仮定してGraphic呼び出しました。canvas.drawBitmap()

明らかに、キャンバスは常に画像の左上から右下に落ちるため、これは機能しません。したがって、解決策は簡単でした。

ソリューション

タッチ位置に関してタッチ領域を作成しますが、x 方向と y 方向の中心位置からイメージ幅を差し引いた距離に相対的に描画します。クラスのアーキテクチャを基本的に変更して、(コンストラクターで決定された) andの値が実際に領域の中心にあるように見せるために、変更されたandを描画する必要がある場所の座標を返すandメソッドGraphicを実装しました。getDrawX()getDrawY()xycenter_xcenter_y

キャンバスがビットマップを描画する方法を補おうとして、残念ながらいくつかの悪い動作を組み込み、最終的にはまったく別の方法でオフセットを処理する必要があったという事実に帰着します。

于 2012-11-14T03:15:20.583 に答える