いつもお世話になっております。
複数の画像があって、ドラッグして移動させるアプリを作っています。
たとえば、カードゲームのUNOみたいなかんじで、
カードを積んだ山から1枚ずつ手元に寄せて…みたいなことをしたいのです。
ところが、
カードの山の1枚目(X)を移動させ終えた(ドロップし終えた)あとに、
またカードの山からカード(Y)を移動させようとドロップすると、
Xが 初期の位置 に戻ってしまうんです(移動した所に留まってくれない)。
この現象は、4.3端末までなら移動した所に留まってくれるんですが、
4.4端末からは、移動した所に留まってくれないんです。
--------------------▼レイアウトXML▼
<?xml version="1.0" encoding="utf-8"?>
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView
android:id="@+id/view1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@drawable/red_card_0"/>
<ImageView
android:id="@+id/view2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@drawable/red_card_1"/>
</FrameLayout>
--------------------▲レイアウトXML▲
FrameLayoutを使っていますが、ルートをRelativeLayoutにしても
同じ現象がおきました。
--------------------▼Activityクラス▼
public class MoveActivity extends Activity implements OnTouchListener {
private View move_view1;
private View move_view2;
int currentX; //Viewの左辺座標:X軸
int currentY; //Viewの上辺座標:Y軸
int offsetX; //画面タッチ位置の座標:X軸
int offsetY; //画面タッチ位置の座標:Y軸
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
move_view1 = findViewById(R.id.view1);
move_view2 = findViewById(R.id.view2);
//リスナーの設定
move_view1.setOnTouchListener(this);
move_view2.setOnTouchListener(this);
}
@Override
public boolean onTouch(View view, MotionEvent event) {
int x = (int) event.getRawX();
int y = (int) event.getRawY();
switch(event.getAction()) {
case MotionEvent.ACTION_MOVE:
int diffX = offsetX - x;
int diffY = offsetY - y;
currentX -= diffX;
currentY -= diffY;
view.layout(currentX, currentY, currentX + view.getWidth(), currentY + view.getHeight());
offsetX = x;
offsetY = y;
break;
case MotionEvent.ACTION_DOWN:
view.bringToFront(); // ※どうしても最前面に出したい
currentX = view.getLeft();
currentY = view.getTop();
offsetX = x;
offsetY = y;
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
}
--------------------▲Activityクラス▲
ポイントは、※印のView#bringToFrontで、
この行をコメントアウトすれば、"初期の位置に戻ってしまう"ということはなくなります。
が、私は、どうしても、
ドラッグ移動させた画像を 最前面に出したい(Zオーダーしたい) のです。
自分なりにソースを調べてみると、
View#bringToFrontは、結局、親View(この場合FrameLayoutイコールViewGroup)の
bringChildToFront(this)を呼び出しているのですが、
--------------------▽API18までのViewGroup#bringChildToFront▽
public void bringChildToFront(View child) {
int index = indexOfChild(child);
if (index >= 0) {
removeFromArray(index);
addInArray(child, mChildrenCount);
child.mParent = this;
}
}
--------------------△API18までのViewGroup#bringChildToFront△
に、対して、KitKatからのViewGroup.javaは、
--------------------▽API19からのViewGroup#bringChildToFront▽
public void bringChildToFront(View child) {
int index = indexOfChild(child);
if (index >= 0) {
removeFromArray(index);
addInArray(child, mChildrenCount);
child.mParent = this;
requestLayout(); // ←これと!
invalidate(); // ←これ!
}
}
--------------------△API19からのViewGroup#bringChildToFront△
と、2行追記の実装変更がされてありました。
にも、
Prior to KITKAT this method should be followed by calls to requestLayout() and invalidate() on the view's parent to force the parent to redraw with the new child ordering.
と書かれてあります。
なんとか、『ドラッグ移動した画像を最前面にさせつつ、その場に留まって欲しい』
のですが、どなたかご教授いただければと存じます。
なにとぞよろしくお願いいたします。