onSingleTapConfirmed没有给出准确的y坐标

时间:2016-04-17 10:03:52

标签: java android android-layout android-studio graphics

MainActivity类使用GestureDetector获取坐标的代码:

public class MainActivity extends AppCompatActivity implements GestureDetector.OnGestureListener,
GestureDetector.OnDoubleTapListener {

    DrawView drawView;
    private GestureDetectorCompat g1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        drawView = new DrawView(this);
        drawView.setBackgroundColor(Color.TRANSPARENT);
        setContentView(drawView);
        g1 = new GestureDetectorCompat(this,this);
        g1.setOnDoubleTapListener(this);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        g1.onTouchEvent(event);
        return super.onTouchEvent(event);
    }

    @Override
    public boolean onSingleTapConfirmed(MotionEvent e) {
        drawView.setXandY(e.getX(), e.getY());
        Log.v("id2","message2");
        return false;
    }

使用此坐标的代码:

public class DrawView extends View {
    Paint paint = new Paint();
    static float x_touch = -1;
    static float y_touch = -1;
    static int [][] arr = new int[][]{{-1,-1,-1},{-1,-1,-1},{-1,-1,-1}};
    static int maxX = -1, maxY = -1;
    public DrawView(Context context) {
        super(context);
        super.setWillNotDraw(false);
        paint.setColor(Color.BLACK);
    }

    @Override
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Display mdisp = ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
        Point mdispSize = new Point();
        mdisp.getSize(mdispSize);
        maxX = mdispSize.x;
        maxY = mdispSize.y;
        canvas.drawLine(maxX/3, 0, maxX/3, maxY, paint);
        canvas.drawLine(maxX*2/3, 0, maxX*2/3, maxY, paint);
        canvas.drawLine(0, maxY / 3, maxX, maxY / 3, paint);//This is first Horizontal line

        canvas.drawLine(0, maxY * 2 / 3, maxX, maxY * 2 / 3, paint); //This is second horizontal line

        Log.v("id1", "message1");
        paint.setTextSize(150f);
        if (x_touch>0 && y_touch>0) {
            if (x_touch < maxX/3 && y_touch < maxY/3)
                canvas.drawText("X", maxX/6, maxY/6, paint);
            else if (x_touch>maxX/3 && x_touch<2*maxX/3 && y_touch<maxY/3)
                canvas.drawText("X", maxX/2, maxY/6, paint);
            else if (x_touch>maxX*2/3 && y_touch<maxY/3)
                canvas.drawText("X", 5*maxX/6, maxY/6, paint);
            else if (x_touch<maxX/3 && y_touch>maxY/3 && y_touch<2*maxY/3)
                canvas.drawText("X", maxX/6, maxY/2, paint);
            else if (x_touch>maxX/3 && x_touch<2*maxX/3 && y_touch>maxY/3 && y_touch<2*maxY/3)
                canvas.drawText("X", maxX/2, maxY/2, paint);
            else if (x_touch>2*maxX/3 && y_touch>maxY/3 && y_touch<2*maxY/3)
                canvas.drawText("X", 5*maxX/6, maxY/2, paint);
            else if (x_touch<maxX/3 && y_touch>2*maxY/3)
                canvas.drawText("X", maxX/6, 5*maxY/6, paint);
            else if (x_touch>maxX/3 && x_touch<2*maxX/3 && y_touch>2*maxY/3)
                canvas.drawText("X", maxX/2, 5*maxY/6, paint);
            else if (x_touch>2*maxX/3 && y_touch>2*maxY/3)
                canvas.drawText("X", 5*maxX/6, 5*maxY/6, paint);
            Log.v("id3", "maxX="+Float.toString(maxX)+" maxY="+Float.toString(maxY)+
                    " x_touch="+Float.toString(x_touch)+" y_touch="+Float.toString(y_touch));
        }
    }

    public void setXandY(float x, float y) {
        x_touch = x;
        y_touch = y;
        this.invalidate();
    }
}

单击第一条水平线以上,在第一条水平线下方打印“X”,在第二条水平线上方点击,在第二条水平线下方打印“X”。

Logcat显示单击第一条水平线以上的值确实会给出大于maxY / 3的值。

编辑:我尝试从应用程序中删除标题栏,其准确性有所改善,但仍然不太准确。

1 个答案:

答案 0 :(得分:1)

问题是您使用MotionEvent onTouchEvent Activity收到的DrawView,因此您收到的坐标是基于活动而非查看基于

要解决您的问题,您可以将手势检测移至public class DrawView extends View implements GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener { private GestureDetectorCompat g1; public DrawView(final Context context) { super(context); g1 = new GestureDetectorCompat(getContext(), this); g1.setOnDoubleTapListener(this); } @Override public boolean onTouchEvent(MotionEvent event) { g1.onTouchEvent(event); return super.onTouchEvent(event); } @Override public boolean onSingleTapConfirmed(MotionEvent e) { setXandY(e.getX(), e.getY()); Log.v("id2","message2"); return false; } }

drawView.setClickable(true);

另外,要在DrawView上接收触摸事件,请不要忘记将其点击:

MotionEvent

根据评论进行修改:

在此示例中,黑色X表示触摸。

documentation

当您收到onTouchEvent的{​​{1}}上的View时,您收到的坐标与查看相关,因此您会收到(124,187)。

当您收到MotionEvent的{​​{1}}上的onTouchEvent时,您收到的坐标与活动相关,因此您会收到(324,487)。

当您在Activity上绘制时,坐标与View相关,因此如果您绘制的坐标与Activity相关,则会绘制红点。