0

更新:質問全体をもう一度読んでください:-)

バックグラウンド:

カスタム ビューを作成し、これらのビューを に追加して、点のグリッドを作成しましたTableLayout。目的は、ドットが押されると、押されたドットの中心から指が現在あるポイントまで線が開始されるように、これらのドットの1つから別のドットに線を引くことができるようにすることです触れる。指を別の点の上にドラッグすると、線はその点の中心で終了します。その結果、押されたドットの中心から指でドラッグされたドットの中心まで線が引かれます。

を超える線を作成するためTableLayoutに、メソッドを使用してポイント間の線を作成した新しいカスタム ビューを作成しましたcanvas.drawLine()。次にFrameLayout、TableLayout と LineView を配置する を作成しました。これは、ライン ビューを TableLayout の上に描画できることを意味していました。

現在の状況:

独自の「タッチ フィードバック」を持つことができるように、DotView クラスにタッチ リスナーを追加しました。アクティビティには、線を引くために必要なポイントを取得するために使用しようとしている別のタッチ リスナーもあります。私が知る限り、タッチ リスナーは問題なく動作しています。相互に干渉していません。

問題は、線をプロットするための正しい座標を取得することです。押されたドットの中心(線の始点)の座標を取得する方法をいくつか試しましたが、まだ管理できていません。この質問には、詳細情報があります:ビューの中心の座標を取得します。2 番目の部分は、線の正しい終点を取得することです。この質問の目的のために、行末を指の位置​​に合わせたいと思います。と同じくらい簡単だと思いましたがmotionevent.getX() / getY()、これはうまくいきませんでした。代わりに、ドットのレイアウトに相対的なスケール上の座標と、レイアウト/画面全体に相対的な座標が混同されていました。

簡単に言えば、getX() と getY() の値が正しくありません。これが、ここで解決しようとしていることです。

スクリーンショットに示されているように、ドットを押し下げると、線の始点はほぼ正しい位置にありますが、終点はかなりずれています。理由は本当に説明できません。

私は試してみgetRawX()ましgetRawY()たが、より正確な値を返しますが、パディングの量によってはまだ正しくありません (またはそのようなもの - 100% 理解していません)。

これは私のコードを示しています

私の中でActivity

    LineView test;
    FrameLayout fl;
     float startPointX = 0;
    float startPointY = 0;

    // Removed 

    @Override
    public boolean onTouch(View view, MotionEvent event) {

        float eventX = event.getX();
        float eventY = event.getY();

        int[] loc = new int[2];

        switch (event.getAction()) {

        case MotionEvent.ACTION_DOWN:

            if (view instanceof DotView) {

                DotView touchedDv = (DotView) view;

                int dotColor = touchedDv.getColor();
                test.setColor(dotColor);

                float[] f = touchedDv.getDotCenterLocationOnScreen();
                startPointX = f[0];
                startPointY = f[1];

                test.setPoints(startPointX, startPointY, eventX, eventY);
fl.addView(test);
            }

            vib.vibrate(35);


            return false; 
        case MotionEvent.ACTION_MOVE:

            test.setPoints(startPointX, startPointY, eventX, eventY);

            break;
        case MotionEvent.ACTION_UP:

            fl.removeView(test);

            return false;

        default:
            return false;
        }

        return true;
    }

そして最後にLineView

public class LineView extends View {

public static final int LINE_WIDTH = 10;
Paint paint = new Paint();

float startingX, startingY, endingX, endingY;

public LineView(Context context) {
    super(context);

    paint.setColor(Color.MAGENTA);
    paint.setStrokeWidth(LINE_WIDTH);

}

public void setPoints(float startX, float startY, float endX, float endY) {

    startingX = startX;
    startingY = startY;
    endingX = endX;
    endingY = endY;
            invalidate();
}


@Override
public void onDraw(Canvas canvas) {

    canvas.drawLine(startingX, startingY, endingX, endingY, paint);

}

ノート:

  • 左上のドットを呼んでい"dot 1"ます。

  • スクリーンショットを撮るときに指がわずかに動くため、スクリーンショットは完全に正確ではないかもしれませんが、説明した動作が発生しています。

スクリーンショット 1

スクリーンショット 2

他の情報/コードが必要な場合は、喜んで提供します。

これを読んでくれてありがとう - 長くなってすみません!

4

1 に答える 1

1

独自の「タッチ フィードバック」を持つことができるように、DotView クラスにタッチ リスナーを追加しました。アクティビティには、線を引くために必要なポイントを取得するために使用しようとしている別のタッチ リスナーもあります。私が知る限り、タッチ リスナーは問題なく動作しています。相互に干渉していません。

両方のタッチリスナーが必要な理由がよくわかりません。線を引くには、 のタッチ リスナーでTableLayout十分です。

コードの問題 (または少なくとも私が見たものから) はgetLocationOnScreen(coordsArray)、返された値を の座標系に変換せずにメソッドを使用することですLineView。たとえば、DotViewx と y になる a の座標を取得します。次に、この値を で使用しますLineView。ただし、LineView描画を行う場合、ビューの左上を (0,0) に配置する独自の (標準) 座標系が使用され、座標が一致しません。以下に例を示します。高さが 50 で、メソッドDotViewによって返される yが 100 である最初のオブジェクトに触れたとします。その中心は125(100 + 50 / 2) になると計算します。この値をgetLocationOnScreen()DotViewLineView実際の描画は 125 で行われるため、通常の位置から大きく外れます。これは、画面座標では視覚的に 225 の y に変換されます (100 はgetLocationOnScreen()+ 125 によって返されます)。

getLocationOnScreen()とにかく、メソッドを使用して、あなたがやろうとしていることを実行する小さな例を作成しました(ここで見つけることができます)。

于 2013-10-29T10:39:59.940 に答える