Android: onTouchListener не работает должным образом

1

В настоящее время я работаю над приложением, которое имеет RelativeLayout, у которого есть 4 дочерних FrameLayouts, каждый FrameLayout имеет набор ImageViews внутри него, а внутри View имеет собственное поведение. Я пытаюсь реализовать перетаскивание в FrameLayouts при реализации onTouchListener я нашел в этом уроке. но, к сожалению, drag-n drop не работает должным образом, и ничего не происходит.

любые мысли о том, как правильно осуществить перетаскивание? что мне не хватает?


вот xml-код для одного дочернего элемента 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>


вот xml-код для 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>


вот код Java для одного ребенка:
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
}


это мой основной код Java:
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;
        }
    };
}
Теги:
android-layout
ontouchlistener

2 ответа

0
Лучший ответ

Почему ваш D & D не работает:

D & D не работает, потому что ваша карта (которая использует внутренний FrameLayout) реализует событие onClick, которое "съедает" событие d & d.

Решения - два:

вы можете иметь две разные области, одну для события клика (самая большая часть карты), одна для события d & d (нижний левый край карты). Вы можете увидеть живой пример в проигрывателе Android Music, который реализует это решение.

В противном случае вы можете обрабатывать два события одновременно:

  • щелкните == вниз + вверх в одно и то же время (до 100 мс) в том же месте x/y
  • dd == down + up в разное время (> 50/100ms)
0

Я думаю, что есть несколько потенциальных проблем:

  1. Вы уверены, что получаете правильные идентификаторы в своем onTouch()? (так как прослушиватель прикосновений используется только с вашими картами, вы, возможно, можете удалить, if проверяете идентификаторы)
  2. Вы используете FrameLayout - поэтому используйте положение x и y вместо редактирования полей: мое плохое, вы используете RelativeLayout, поэтому поля являются правильными. Хотя, я бы использовал FrameLayout вместо
  3. API говорит, что вам нужно вернуть true в onTouch() если вы потребляете событие, в противном случае false (вы возвращаете true когда вы не перемещали карты и ничего не делали)
  • 0
    Привет Брайан, onTouch() не вызывается вообще

Ещё вопросы

Сообщество Overcoder
Наверх
Меню