在我创建的自定义 ViewGroup 上定位视图元素时遇到问题,特别是在拖放情况下。我的目标是 Android 2.2 及更高版本,所以我不能真正使用 Android 3 中出现的拖放 API。
我的自定义 ViewGroup 称为“NodeGrid”,它扩展了“RelativeLayout”。它的onLayout方法被覆盖,如下所示:
@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);
}
}
}
“NodeGrid”的子节点属于“NodeView”类型(如您在上面的代码中所见)。NodeView 只是我创建的一个自定义 View 类。它包含一个名为“DataContext”的成员,它是一个视图模型类,其中包含一些 getter/setter,其中包含有关 NodeGrid 上的 NodeView 实例的位置信息。
我的“NodeView”类捕获用户的触摸事件,因此用户可以简单地将节点拖放到网格上的任何位置。事件处理程序如下所示:
@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;
}
我的问题是被拖动的视图没有像我期望的那样定位在我的“NodeGrid”上。当我拖动它时,x 轴位置似乎是正确的,但 y 轴位置在任何时候都会偏移一些恒定数量的像素。什么会导致这种情况?我尝试使用 getX() 和 getY() 方法而不是 getRawX() 和 getRawY(),但这只会导致情况更糟。
我不确定 getRawX() 和 getRawY() 是返回 px 单位还是 dip 单位给我,所以期待它返回 px 单位,我尝试在将新的 x 和 y 值分配给之前将它们转换为 dip 单位节点,但这只是减少了偏移量,并没有消除它。
什么可能导致我触摸的位置和节点的位置不同?