В настоящее время я работаю над приложением, которое имеет RelativeLayout
, у которого есть 4 дочерних FrameLayouts
, каждый FrameLayout имеет набор ImageViews внутри него, а внутри View имеет собственное поведение. Я пытаюсь реализовать перетаскивание в FrameLayouts
при реализации onTouchListener
я нашел в этом уроке. но, к сожалению, drag-n drop не работает должным образом, и ничего не происходит.
любые мысли о том, как правильно осуществить перетаскивание? что мне не хватает?
FrameLayouts
: <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="80dp"
android:layout_height="108dp" >
<ImageView
android:id="@+id/secondImage"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:src="@drawable/back" />
<ImageView
android:id="@+id/firstImage"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:src="@drawable/c2" />
</FrameLayout>
main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/pinecropped"
android:orientation="vertical" >
<FrameLayout
android:id="@+id/cardNumber1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
android:layout_marginTop="60dp" >
<include layout="@layout/card" />
</FrameLayout>
<FrameLayout
android:id="@+id/cardNumber2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/cardNumber1"
android:layout_marginLeft="50dp"
android:layout_marginTop="100dp" >
<include layout="@layout/card" />
</FrameLayout>
<FrameLayout
android:id="@+id/cardNumber3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginRight="50dp"
android:layout_marginTop="60dp" >
<include layout="@layout/card" />
</FrameLayout>
<FrameLayout
android:id="@+id/cardNumber4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="@+id/cardNumber3"
android:layout_marginRight="50dp"
android:layout_marginTop="100dp" >
<include layout="@layout/card" />
</FrameLayout>
</RelativeLayout>
public class Card implements OnClickListener {
private int _resId;
private Context _context;
private ImageView firstImage, secondImage;
private boolean isFirst;
public Card(Context context, FrameLayout parent) {
_context = context;
firstImage = (ImageView) parent.findViewById(R.id.firstImage);
secondImage = (ImageView) parent.findViewById(R.id.secondImage);
}
public void setupCards(int resId, boolean hasBackSide) {
_resId = resId;
Bitmap temp = BitmapFactory.decodeResource(_context.getResources(),
_resId);
firstImage.setImageBitmap(temp);
if (hasBackSide) {
temp = BitmapFactory.decodeResource(_context.getResources(),
R.drawable.back);
}
secondImage.setImageBitmap(temp);
isFirst = true;
secondImage.setVisibility(View.GONE);
}
// MORE IMPLEMENTATION
}
public class FaceUpActivity extends Activity {
FrameLayout firstCard, secondCard, thirdCard, forthCard;
Card cardNumber1, cardNumber2, cardNumber3, cardNumber4;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
initUI();
}
private void initUI() {
firstCard = (FrameLayout) findViewById(R.id.cardNumber1);
secondCard = (FrameLayout) findViewById(R.id.cardNumber2);
thirdCard = (FrameLayout) findViewById(R.id.cardNumber3);
forthCard = (FrameLayout) findViewById(R.id.cardNumber4);
cardNumber1 = new Card(this, firstCard);
cardNumber2 = new Card(this, secondCard);
cardNumber3 = new Card(this, thirdCard);
cardNumber4 = new Card(this, forthCard);
cardNumber1.setupCards(R.drawable.c2, true);
cardNumber2.setupCards(R.drawable.d0, true);
cardNumber3.setupCards(R.drawable.h5, true);
cardNumber4.setupCards(R.drawable.sj, true);
firstCard.setOnTouchListener(dragMe);
secondCard.setOnTouchListener(dragMe);
thirdCard.setOnTouchListener(dragMe);
forthCard.setOnTouchListener(dragMe);
}
OnTouchListener dragMe = new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
FrameLayout.LayoutParams params = (LayoutParams) v
.getLayoutParams();
int maxWidth = getWindowManager().getDefaultDisplay().getWidth();
int maxHeight = getWindowManager().getDefaultDisplay().getHeight();
int topMargin, leftMargin;
int cond = v.getId();
if (cond == R.id.cardNumber1 || cond == R.id.cardNumber2
|| cond == R.id.cardNumber3 || cond == R.id.cardNumber4) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
topMargin = (int) event.getRawY() - (v.getHeight());
leftMargin = (int) event.getRawX() - (v.getWidth()) / 2;
if (topMargin < 0) {
params.topMargin = 0;
} else if (topMargin > maxHeight) {
params.topMargin = maxHeight - v.getHeight();
} else {
params.topMargin = topMargin;
}
if (leftMargin < 0) {
params.leftMargin = 0;
} else if (leftMargin > maxWidth) {
params.leftMargin = maxWidth - (v.getWidth() / 2);
} else {
params.leftMargin = leftMargin;
}
v.setLayoutParams(params);
break;
case MotionEvent.ACTION_MOVE:
topMargin = (int) event.getRawY() - (v.getHeight());
leftMargin = (int) event.getRawX() - (v.getWidth()) / 2;
if (topMargin < 0) {
params.topMargin = 0;
} else if (topMargin > maxHeight) {
params.topMargin = maxHeight - v.getHeight();
} else {
params.topMargin = topMargin;
}
if (leftMargin < 0) {
params.leftMargin = 0;
} else if (leftMargin > maxWidth) {
params.leftMargin = maxWidth - (v.getWidth() / 2);
} else {
params.leftMargin = leftMargin;
}
v.setLayoutParams(params);
break;
}
}
return true;
}
};
}
Почему ваш D & D не работает:
D & D не работает, потому что ваша карта (которая использует внутренний FrameLayout) реализует событие onClick, которое "съедает" событие d & d.
Решения - два:
вы можете иметь две разные области, одну для события клика (самая большая часть карты), одна для события d & d (нижний левый край карты). Вы можете увидеть живой пример в проигрывателе Android Music, который реализует это решение.
В противном случае вы можете обрабатывать два события одновременно:
Я думаю, что есть несколько потенциальных проблем:
onTouch()
? (так как прослушиватель прикосновений используется только с вашими картами, вы, возможно, можете удалить, if
проверяете идентификаторы)FrameLayout
- поэтому используйте положение x и y вместоRelativeLayout
, поэтому поля являются правильными. Хотя, я бы использовал FrameLayout
вместоtrue
в onTouch()
если вы потребляете событие, в противном случае false
(вы возвращаете true
когда вы не перемещали карты и ничего не делали)
onTouch()
не вызывается вообще