特にドラッグアンドドロップの状況で、作成したカスタムViewGroupにビュー要素を配置するのに問題があります。Android 2.2以降をターゲットにしているため、Android3で登場したドラッグアンドドロップ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クラスです。これには、NodeGrid上のNodeViewインスタンスに関する位置情報を持ついくつかのゲッター/セッターを含むビューモデルクラスである「DataContext」と呼ばれるメンバーが含まれています。
私の「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軸の位置は常に一定量のピクセルによってオフセットされています。これを引き起こしているのは何ですか?getRawX()およびgetRawY()ではなくgetX()およびgetY()メソッドを使用しようとしましたが、それが原因で悪化するだけです。
getRawX()とgetRawY()がpx単位を返すのか、dip単位を返すのかわからなかったので、px単位が返されることを期待して、新しいx値とy値をに割り当てる前にそれらをdip単位に変換してみました。ノードですが、それはオフセットを減少させるだけで、それを排除しませんでした。
タッチしている場所とノードが配置されている場所の違いの原因は何ですか?