2

前の質問を始めましたが、ドラッグの方法を変更したいと思います。

つまり、タスクは、ユーザー(子供)が足し算の方法を学ぶことです。つまり、2つのキャンディーと1つのキャンディージャーがあります。ユーザーはキャンディーを瓶にドラッグアンドドロップする必要があります。どうやってするの?

これらは私が持っているコードです:

メインxml

<?xml version="1.0" encoding="utf-8"?>


<AbsoluteLayout android:layout_width="fill_parent" android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/mainLayout">
<ImageView android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/emptyLetterView" android:src="@drawable/r_empty" android:layout_x="200px" android:layout_y="300px"></ImageView>
<ImageView android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/letterView" android:src="@drawable/r_filled" ></ImageView>
</AbsoluteLayout>

これは、Javaファイルパッケージedu.sbcc.cs123.draganddropbasicです。

import android.app.*;
import android.graphics.*;
import android.os.*;
import android.view.*;
import android.view.View.*;
import android.widget.*;

@SuppressWarnings("deprecation")
public class DragAndDropBasicActivity extends Activity implements OnTouchListener {
    private ImageView letterView;                       // The letter that the user drags.
    private ImageView emptyLetterView;              // The letter outline that the user is supposed to drag letterView to.
    private AbsoluteLayout mainLayout;


    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mainLayout = (AbsoluteLayout) findViewById(R.id.mainLayout);
        mainLayout.setOnTouchListener(this);
        letterView = (ImageView) findViewById(R.id.letterView);
        letterView.setOnTouchListener(this);

        emptyLetterView = (ImageView) findViewById(R.id.emptyLetterView);
    }

    private boolean dragging = false;
    private Rect hitRect = new Rect();

    @Override
    /**
     * NOTE:  Had significant problems when I tried to react to ACTION_MOVE on letterView.   Kept getting alternating (X,Y) 
     * locations of the motion events, which caused the letter to flicker and move back and forth.  The only solution I could 
     * find was to determine when the user had touched down on the letter, then process moves in the ACTION_MOVE 
     * associated with the mainLayout.
     */
    public boolean onTouch(View v, MotionEvent event) {
        boolean eventConsumed = true;
        int x = (int)event.getX();
        int y = (int)event.getY();

        int action = event.getAction();
        if (action == MotionEvent.ACTION_DOWN) {
            if (v == letterView) {
                dragging = true;
                eventConsumed = false;
            }
        } else if (action == MotionEvent.ACTION_UP) {

            if (dragging) {
                emptyLetterView.getHitRect(hitRect);
                if (hitRect.contains(x, y))
                    setSameAbsoluteLocation(letterView, emptyLetterView);
            }
            dragging = false;
            eventConsumed = false;

        } else if (action == MotionEvent.ACTION_MOVE) {
            if (v != letterView) {
                if (dragging) {
                    setAbsoluteLocationCentered(letterView, x, y);
                }
            }
        }

        return eventConsumed;

    }


    private void setSameAbsoluteLocation(View v1, View v2) {
        AbsoluteLayout.LayoutParams alp2 = (AbsoluteLayout.LayoutParams) v2.getLayoutParams();
        setAbsoluteLocation(v1, alp2.x, alp2.y);
    }


    private void setAbsoluteLocationCentered(View v, int x, int y) {
        setAbsoluteLocation(v, x - v.getWidth() / 2, y - v.getHeight() / 2);
    }


    private void setAbsoluteLocation(View v, int x, int y) {
        AbsoluteLayout.LayoutParams alp = (AbsoluteLayout.LayoutParams) v.getLayoutParams();
        alp.x = x;
        alp.y = y;
        v.setLayoutParams(alp);
    }
}

そして、これは私がしばらくの間実装してきたものです。新しい変数を追加して、letterView1とemptyLetterView1に変更するだけです。

Javaファイル:

package edu.sbcc.cs123.draganddropbasic;

import android.app.*;
import android.graphics.*;
import android.os.*;
import android.view.*;
import android.view.View.*;
import android.widget.*;

@SuppressWarnings("deprecation")
public class DragAndDropBasicActivity extends Activity implements OnTouchListener {
    private ImageView letterView;                       // The letter that the user drags.
    private ImageView emptyLetterView;          // The letter outline that the user is supposed to drag letterView to.
    private ImageView letterView1;                      // The letter that the user drags.
    private ImageView emptyLetterView1; 
    private AbsoluteLayout mainLayout;


    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mainLayout = (AbsoluteLayout) findViewById(R.id.mainLayout);
        mainLayout.setOnTouchListener(this);
        letterView = (ImageView) findViewById(R.id.letterView);
        letterView.setOnTouchListener(this);

        emptyLetterView = (ImageView) findViewById(R.id.emptyLetterView);

        letterView1 = (ImageView) findViewById(R.id.letterView1);
        letterView1.setOnTouchListener(this);

        emptyLetterView1 = (ImageView) findViewById(R.id.emptyLetterView1);
    }

    private boolean dragging = false;
    private Rect hitRect = new Rect();

    @Override
    /**
     * NOTE:  Had significant problems when I tried to react to ACTION_MOVE on letterView.   Kept getting alternating (X,Y) 
     * locations of the motion events, which caused the letter to flicker and move back and forth.  The only solution I could 
     * find was to determine when the user had touched down on the letter, then process moves in the ACTION_MOVE 
     * associated with the mainLayout.
     */
    public boolean onTouch(View v, MotionEvent event) {
        boolean eventConsumed = true;
        int x = (int)event.getX();
        int y = (int)event.getY();

        int action = event.getAction();
        if (action == MotionEvent.ACTION_DOWN) {
            if (v == letterView) {
                dragging = true;
                eventConsumed = false;
            }
            if (v == letterView1) {
                dragging = true;
                eventConsumed = false;
            }
        } else if (action == MotionEvent.ACTION_UP) {

            if (dragging) {
                emptyLetterView.getHitRect(hitRect);
                if (hitRect.contains(x, y))
                    setSameAbsoluteLocation(letterView, emptyLetterView);
            }

            if (dragging) {
                emptyLetterView1.getHitRect(hitRect);
                if (hitRect.contains(x, y))
                    setSameAbsoluteLocation1(letterView1, emptyLetterView1);
            }
            dragging = false;
            eventConsumed = true;

        } else if (action == MotionEvent.ACTION_MOVE) {
            if (v != letterView) {
                if (dragging) {
                    setAbsoluteLocationCentered(letterView, x, y);
                }
            }
            if (v != letterView1) {
                if (dragging) {
                    setAbsoluteLocationCentered1(letterView1, x, y);
                }
            }
        }

        return eventConsumed;

    }


    private void setSameAbsoluteLocation(View v1, View v2) {
        AbsoluteLayout.LayoutParams alp2 = (AbsoluteLayout.LayoutParams) v2.getLayoutParams();
        setAbsoluteLocation(v1, alp2.x, alp2.y);
    }


    private void setAbsoluteLocationCentered(View v, int x, int y) {
        setAbsoluteLocation(v, x - v.getWidth() / 2, y - v.getHeight() / 2);
    }


    private void setAbsoluteLocation(View v, int x, int y) {
        AbsoluteLayout.LayoutParams alp = (AbsoluteLayout.LayoutParams) v.getLayoutParams();
        alp.x = x;
        alp.y = y;
        v.setLayoutParams(alp);
    }




    private void setSameAbsoluteLocation1(View v1, View v2) {
        AbsoluteLayout.LayoutParams alp2 = (AbsoluteLayout.LayoutParams) v2.getLayoutParams();
        setAbsoluteLocation1(v1, alp2.x, alp2.y);
    }


    private void setAbsoluteLocationCentered1(View v, int x, int y) {
        setAbsoluteLocation1(v, x - v.getWidth() / 2, y - v.getHeight() / 2);
    }


    private void setAbsoluteLocation1(View v, int x, int y) {
        AbsoluteLayout.LayoutParams alp = (AbsoluteLayout.LayoutParams) v.getLayoutParams();
        alp.x = x;
        alp.y = y;
        v.setLayoutParams(alp);
    }
}

画像ファイルをxmlファイルに追加し、IDをletterView1とemptyLetterView1にも変更しました。

そのため、別の画像は正常に表示されますが、画像の1つをドラッグすると、別の画像が消えました。

どうすればこれを実装できますか?

4

2 に答える 2

3

私はあなたの解決策を以下のコード/情報に基づいています:

于 2013-01-12T10:04:05.120 に答える
1

あなたのコードの問題はここにあります

else if (action == MotionEvent.ACTION_MOVE) {
        if (v != letterView) {
            if (dragging) {
                setAbsoluteLocationCentered(letterView, x, y);
            }
        }
        if (v != letterView1) {
            if (dragging) {
                setAbsoluteLocationCentered1(letterView1, x, y);
            }
        }
    }

以前のコードには、2つのリスナーがありました。

  1. 主な背景
  2. letterView

これで3人のリスナーif (v != letterView)ができたので、ユーザーが地面または手紙をドラッグしている場合に当てはまります。

たとえば、画面のランダムなパッチをドラッグし始めた場合は、v!=letterViewv!=letterView1。それらは両方とも同じポイントの中央に配置されるため、一方が隠れているように見えます。

それらの1つをドラッグしても、同じことが当てはまります。もう一方はそのポイントに移動し、非表示になります。

非方程式を使用する代わりに、試すことができます

else if (action == MotionEvent.ACTION_MOVE) {
        if (v == letterView) {
            if (dragging) {
                setAbsoluteLocationCentered(letterView, x, y);
            }
        }
        if (v == letterView1) {
            if (dragging) {
                setAbsoluteLocationCentered1(letterView1, x, y);
            }
        }
    }

または、ヒットテストを行うこともできます

   else if (action == MotionEvent.ACTION_MOVE) {
        letterView.getHitRect(hitRect);
        if (letterView.contains(x,y)) {
            if (dragging) {
                setAbsoluteLocationCentered(letterView, x, y);
            }
        }
        letterView1.getHitRect(hitRect);
        if (letterView1.contains(x,y)) {
            if (dragging) {
                setAbsoluteLocationCentered1(letterView1, x, y);
            }
        }
  }
于 2013-01-13T10:00:52.710 に答える