画线以下的手指 - motionevent.getX()和getY()以不正确更新不正确、手指、画线、motionevent

2023-09-06 07:08:13 作者:单身汪保护协会会长

更新:请再次阅读整个问题: - )

背景:

我已经通过创建自定义视图,然后将这些意见向 TableLayout 创建点的网格。这样做的目的是让我能够从这些点中的一个画线至另一点的方式,这样,当一个点是pressed,一条线从pssed点到所述$ P $的中心开始点手指当前感人。当手指被拖到另一点,线然后结束在该点的中心。从pssed点向其中拖过由手指的点的中心的$ P $中心的结果被一个线描绘

要建立一个行会在 TableLayout ,我创建了刚刚创建点之间的直线与一个新的自定义视图中的 canvas.drawLine( )方法。然后,我创建了一个的FrameLayout 中,我把TableLayout和LineView。这意味着该行视图将能够在TableLayout的顶端被吸入

现状:

我在DotView类增添一抹侦听器,以便它可以有自己的触感反馈。还有另一个触摸听者的活动,我想使用去画线所需要的点。触摸监听器工作正常,据我可以告诉 - 他们不相互干扰

该问题得到正确的坐标绘制的线。我已经尝试了许多方法来获得,这是pressed(该线的起点)点的中心坐标,但是我还没有做的。这个问题,有更多的信息:得到一个视图的中心坐标。第二部分是让行的正确终点。对于这个问题的目的,我只是想在行尾跟随手指的位置。我认为这是因为容易motionevent.getX()/ getY()以但是这并没有奏效。发生了什么事,而不是是,有一个混合起来刻度相对于所述点的布局和相对于整个布局/屏幕坐标一个坐标之间。

简单地说:在信息getX()和getY()以值是不正确的,这就是我想在这里解决。

如图中的截图,当我preSS倒在一个点,线的起点大约是在正确的地方,但终点的路要走。我真的不能解释为什么。

我已经试过 getRawX() getRawY(),他们返回更多更准确的数值,但他们仍然不正确用的填充量(或类似的东西 - 我不100%理解​​)

这说明我的code

怎么在Android应用中实现一个贝塞尔曲线

在我的活动

  LineView测试;
    的FrameLayout FL;
     浮startPointX = 0;
    浮startPointY = 0;

    //删除

    @覆盖
    公共布尔onTouch(查看视图,MotionEvent事件){

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

        INT [] LOC =新INT [2];

        开关(event.getAction()){

        案例MotionEvent.ACTION_DOWN:

            如果(查看的instanceof DotView){

                DotView touchedDv =(DotView)视图;

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

                浮动[] F = touchedDv.getDotCenterLocationOnScreen();
                startPointX = F [0];
                startPointY = F [1];

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

            vib.vibrate(35);


            返回false;
        案例MotionEvent.ACTION_MOVE:

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

            打破;
        案例MotionEvent.ACTION_UP:

            fl.removeView(试验);

            返回false;

        默认:
            返回false;
        }

        返回true;
    }
 

最后的 LineView

 公共类LineView扩展视图{

公共静态最终诠释LINE_WIDTH = 10;
涂料粉刷=新的油漆();

浮startingX,startingY,endingX,endingY;

公共LineView(上下文的背景下){
    超(上下文);

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

}

公共无效设定值(STARTX浮动,浮动startY,浮endX,浮恩迪){

    startingX = STARTX;
    startingY = startY;
    endingX = endX;
    endingY =恩迪;
            无效();
}


@覆盖
公共无效的OnDraw(帆布油画){

    canvas.drawLine(startingX,startingY,endingX,endingY,油漆);

}
 

注:

我打电话左上角点点1

的屏幕截图可能不完全准确的,因为我的手指动作 稍微当我把截图,但我所描述的行为 发生的事情。

如果任何其他信息/ code是想要的,我会很乐意提供。

感谢您抽出时间来阅读这篇文章的时候 - 抱歉,这是这么长时间

! 解决方案   

我在DotView类增添一抹侦听器,以便它可以有   自己的触摸反馈。还有另一个触摸听者在   活动我想使用去绘制所需的点   线。触摸监听器工作正常,据我可以告诉 - 他们   不相互干扰。

我不太明白为什么你既需要触摸监听器。要划清界线上的触摸听者的 TableLayout 应该是绰绰有余。

您code中的问题(或者至少从我所看到的)是您使用 getLocationOnScreen将(coordsArray)方法,无需转换返回值回到 LineView 的坐标系。例如,你会得到一个 DotView 这将是x和y的坐标。然后,在 LineView 使用这个值。但是,在 LineView 时,它会做它的图纸将使用自己的(标准)坐标系统会将左上角(0,0)的观点和坐标将不匹配。这里有一个例子:假设你接触的第一个 DotView 其中有50的高度,并通过 getLocationOnScreen将()方法是100。您计算 DotView中心至极会是在125(100 + 50/2)。使用这个值 LineView 将路要走恢复正常位置作为实际的绘制工作将在125,它在屏幕坐标在视觉上就会转化为AY 225(100通过 getLocationOnScreen将() + 125)。

反正我做了使用 getLocationOnScreen将()方法做你想要做什么(你可以找到这里)。

UPDATE: please read entire question again :-)

Background:

I have created a grid of dots by creating a custom view and then adding these views to a TableLayout. The aim is for me to be able to draw a line from one of these dots to another dot in a way so that when a dot is pressed, a line is started from the center of the pressed dot to the point where the finger is currently touching. When the finger is dragged over another dot, the line then finishes at the center of that dot. The result being a line drawn from the center of the pressed dot to the center of the dot which was dragged over by the finger.

To create a line going over the TableLayout, I created a new custom view which just created a line between points with the canvas.drawLine() method. I then created a FrameLayout in which I put the TableLayout and the LineView. This meant the line view would be able to be drawn on top of the TableLayout.

Current Situation:

I have added touch listener in the DotView class so that it can have its own "touch feedback". There is also another touch listener in the activity which I am trying to use to get the points needed to draw the line. The touch listeners are working fine as far as I can tell - they are not interfering with each other.

The problem is getting the correct coordinates to plot the line. I have tried a number of ways to get the coordinates of the center of the dot that was pressed (the starting point of the line), but I still have not managed it. This question, has more information: Get the coordinates of the center of a view . The second part is getting the correct end point of the line. For the purposes of this question, I would just like the end of the line to follow the position of the finger. I thought it was as easy as motionevent.getX() / getY() but this hasn’t worked. What happened instead was that there was a mix up between the coordinates on a scale relative to the layout of the dot and the coordinates relative to the whole layout/screen.

Simply put: the getX() and getY() values are incorrect, and this is what I am trying to solve here.

As shown in the screenshots, when I press down on a dot, the start point of the line is roughly in the right place, but the end point is way off. I can’t really explain why.

I have tried getRawX() and getRawY() and they return more much more accurate values, but they are still incorrect by the amount of padding (or something like that - I don’t 100% understand).

This shows my code

In my 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;
    }

And finally the 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);

}

NOTES:

I am calling the top left hand dot "dot 1".

The screenshots may not be entirely accurate as my finger moves slightly when I take the screenshot, but the behaviour I described is happening.

If any other information/code is wanted, I will happily provide it.

Thanks for taking the time to read this - sorry it is so long!

解决方案

I have added touch listener in the DotView class so that it can have its own "touch feedback". There is also another touch listener in the activity which I am trying to use to get the points needed to draw the line. The touch listeners are working fine as far as I can tell - they are not interfering with each other.

I don't quite see why you need both touch listener. To draw the line the touch listener on the TableLayout should be more than enough.

The problem with your code(or at least from what I've seen) is that you use the getLocationOnScreen(coordsArray) method without translating the returned values back to the coordinates system of the LineView. For example, you get the coordinates of a DotView which will be x and y. You then use this values in the LineView. But, the LineView when it will do its drawings will use its own(standard) coordinates system which places the top-left of the view at (0,0) and the coordinates will not match. Here's an example: suppose you touch the very first DotView which has a height of 50 and the y returned by the getLocationOnScreen() method is 100. You calculate the center of the DotView wich will come be at 125(100 + 50 / 2). Using this value in the LineView will be way off the normal position as the actual drawing will be done at 125, which in screen coordinates will visually translate to a y of 225 (100 returned by getLocationOnScreen() + 125).

Anyway I've made a small example using the getLocationOnScreen() method to do what you're trying to do(which you can find here).