1

私は現在、RelativeLayout4 つの child を持つアプリに取り組んでいFrameLayoutsます。各 FrameLayout には一連の ImageView があり、内側の View には独自の動作があります。このチュートリアルで見つけたFrameLayoutsを実装しながら、へのドラッグ アンド ドロップを実装しようとしています。残念ながら、ドラッグ アンド ドロップが正しく機能せず、何も起こっていません。onTouchListener

ドラッグアンドドロップを正しく実装する方法について何か考えはありますか? 私は何が欠けていますか?


の単一の子の 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;
        }
    };
}
4

2 に答える 2

0

I think there are a couple of potential problems:

  1. Are you sure you're getting the correct IDs in your onTouch()? (since the touch listener is only used with your card views, you propably can remove the if checking for the IDs)
  2. You are using a FrameLayout - so use the x and y position instead of margins edit: my bad, you're using RelativeLayout, so the margins are kind of right. Though, I'd use a FrameLayout instead
  3. the API says you need to return true in onTouch() if you consumed the event, false otherwise (you're returning true when you didn't move the cards and nothing when you did)
于 2012-06-04T10:58:39.850 に答える
0

D&D が機能しない理由:

カード (内部 FrameLayout を使用する) が d&d イベントを「食べる」 onClick イベントを実装しているため、D&D が機能していません。

解決策は次の 2 つです。

1 つはクリック イベント (カードの最大部分) 用、もう 1 つは d&d イベント (カードの左下端) 用の 2 つの異なる領域を持つことができます。このソリューションを実装する Android ミュージック プレーヤーで実際の例を確認できます。

それ以外の場合は、2 つのイベントを同時に処理できます。

  • 同じ x/y 位置で同時に (100 ミリ秒未満) == down+up をクリック
  • dd == 異なる時間でダウン + アップ (> 50/100ms)
于 2012-06-05T09:29:25.593 に答える