У меня возникают проблемы с позиционированием элементов представления в пользовательской группе просмотра, которую я создал, особенно в ситуациях перетаскивания. Я нацелен на 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 или единицы наклона, поэтому, ожидая, что он вернет мне единицы px, я попытался преобразовать их в единицы наклона, прежде чем назначать новые значения x и y для узел, но это только уменьшило смещение, но не устранило его.
Что может быть причиной разницы в том, где я касаюсь и где находится узел?