androidandroid-layoutcoordinates

Coordinates for view inside custom view don't match at all


I'm working on a family-tree like app. I use a force-directed layout algorithm to calculate the positions on which the nodes will be placed. The nodes are a custom view that I created myself called PersonCard. Here's a snippet from my PersonCard:

private void init(AttributeSet attrs) {
        // Initialize anchors
        rightAnchor = new View(getContext());
        int anchorColor = ContextCompat.getColor(getContext(), R.color.tea_rose);
        int anchorSize = 10;
        rightAnchor.setBackgroundColor(anchorColor);

        FrameLayout.LayoutParams rightAnchorParams = new FrameLayout.LayoutParams(anchorSize, anchorSize);
        rightAnchorParams.gravity = Gravity.CENTER_VERTICAL | Gravity.RIGHT;
        rightAnchorParams.rightMargin = -padding;
        rightAnchor.setLayoutParams(rightAnchorParams);

        addView(rightAnchor);
    }

Because I will need to connect these different PersonCards, I created different anchors (one on each side of a PersonCard) so that there are unified spots where I can connect my PersonCards with a Line view.

After the algorithm has calculated the positions for each PersonCard, I get the x and y coordinates like this and place the PersonCards accordingly:

Node 1: (489.70685469968083, 1534.7124300016587)
Node 2: (995.1782137460826, 731.7942097127028)
Node 3: (58.578329522505925, 716.785942983157)
Node 4: (534.2392750542016, 996.037653894383)
Node 5: (43.46557962124075, 1243.6774403463626)
Node 6: (530.856915894992, 454.41864708395013)
Node 7: (978.3108846322139, 1287.7832880796614)

In my PersonCard, I created methods to get the position of the anchors:

private int[] getAnchorPosition(ViewGroup parent, View anchor) {
        int[] anchorPosition = new int[2];
        int[] parentPosition = new int[2];

        anchor.getLocationOnScreen(anchorPosition);

        parent.getLocationOnScreen(parentPosition);

        anchorPosition[0] -= parentPosition[0];
        anchorPosition[1] -= parentPosition[1];

        Log.d("AnchorPosition", "Anchor X: " + anchorPosition[0] + ", Y: " + anchorPosition[1]);
        return anchorPosition;
    }

    public int[] getRightAnchorPosition(ViewGroup parent) {
        return getAnchorPosition(parent, rightAnchor);
    }

However, how can it be that this method gives me completely wrong coordinates? When I call it, it gives me something like this for the rightAnchor of Node 1:

Node 1: X is: 200, Y is: 203

As you can see, this doesn't match the real coordinates of Node 1 at all. And for some strange reason, all the other rightAnchors of the PersonCards have the same coordinates?

Node 2: X is: 200, Y is: 203
Node 3: X is: 200, Y is: 203
Node 4: X is: 200, Y is: 203
and so on...

I'm not sure where this weird behaviour stems from. As for my layout, I just add my PersonCards to a FrameLayout, which is the child of another FrameLayout.

In order not to fall for some layout computing shenanigans, I used .post to make sure my layout has finished computing before I call getRightAnchorPosition:

personCard.post(new Runnable() {
                    @Override
                    public void run() {
                        int[] rightAnchorPos = personCard.getRightAnchorPosition(origin_frameLayout);
                        Log.d("RightAnchor", "X is: " + rightAnchorPos[0] + ", Y is: " + rightAnchorPos[1]);
                    }
                });

However, this still gives me the same coordinates that I showed above.

Why exactly do I get this weird behaviour, and how can I possibly fix it?


Solution

  • Of course it was a problem with the lifecycle of my activity. When I use ViewTreeObserver.OnGlobalLayoutListener instead of .post, the coordinates are returned perfectly.