У меня проблемы с размещением элементов вида в созданной мной пользовательской группе, особенно в ситуациях перетаскивания. Я нацеливаюсь на Android 2.2 и выше, поэтому я не могу использовать API перетаскивания, который появился в Android 3.
Моя пользовательская 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», который является классом модели представления, который содержит некоторые методы получения / установки с информацией о положении экземпляра NodeView в NodeGrid.
Мой класс "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-единицы, я попытался преобразовать их в dip-единицы перед назначением нового x и значения y для узла, но это только уменьшило смещение, но не устранило его.
Что может быть причиной различий в том, где я касаюсь и где расположен узел?