I am having problems positioning view elements in the custom ViewGroup I created, especially in drag and drop situations. I am targeting Android 2.2 and higher, so I cannot use the drag and drop API introduced in Android 3.
My custom ViewGroup is called "NodeGrid" and it extends "RelativeLayout". Its onLayout method is overridden so that it looks like this:
@Override protected void onLayout(boolean arg0, int arg1, int arg2, int arg3, int arg4) { //pxConversion is a multiplier to convert 1 dip to x pixels. //We will use it to convert dip units into px units. Resources r = getResources(); float pxConversion = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, r.getDisplayMetrics()); //Layout the children of this viewgroup int childCount = this.getChildCount(); for (int i = 0; i < childCount; i++) { NodeView view = (NodeView) this.getChildAt(i); if (view.DataContext != null) { int left = (int) (view.DataContext.get_left() * pxConversion); int top = (int) (view.DataContext.get_top() * pxConversion); int right = left + (int) (view.DataContext.get_width() * pxConversion); int bottom = top + (int) (view.DataContext.get_height() * pxConversion); view.layout(left, top, right, bottom); } } }
Children from NodeGrid are of type NodeView (as you can see in the code above). NodeView is a simple custom View class that I created. It contains an element called "DataContext", which is a view model class that contains some getters / setters with location information for the NodeView instance in the NodeGrid.
My "NodeView" class captures touch events by the user, so the user can simply drag the node anywhere on the grid. The event handler is as follows:
@Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { isBeingDragged = true; } else if (event.getAction() == MotionEvent.ACTION_UP) { isBeingDragged = false; } else if (event.getAction() == MotionEvent.ACTION_MOVE) { if (DataContext != null && isBeingDragged) { float xPosition = event.getRawX(); float yPosition = event.getRawY(); DataContext.set_left(xPosition); DataContext.set_top(yPosition); this.requestLayout(); } } return true; }
My problem is that the view being viewed is not positioned as I expect on my "NodeGrid". It seems that the position of the x axis is correct when I drag it, but the position of the y axis is shifted by a number of pixels at any time. What could be the reason for this? I tried using the getX () and getY () methods, not getRawX () and getRawY (), but that only worsens it.
I was not sure if getRawX () and getRawY () would return units of units or drop units to me, so expecting it to return units of px to me, I tried converting them to dip units before assigning new x and y to node but it only reduced the displacement, it did not eliminate it.
What can cause a difference in where I touch and where the node is?