Android-новичок - Поместите изображение в DragEvent

Я понимаю, что подобные вопросы были опубликованы, и я просмотрел их и множество других тем и т.д., чтобы найти решение - я явно не вижу очевидного - поскольку я все еще изучаю основы!

Цель: простое перетаскивание. Пользователь перемещает изображение по экрану и либо падает поверх другого изображения, либо в любом месте экрана.

API: > 11

Выполнил:

  • Можно перетащить изображение и разместить поверх другого изображения и получить ответ (с помощью Toast для подтверждения).
  • Можно перетащить изображение в любом месте экрана и получить ответ (используя Toast для подтверждения).

НЕ работает:

  • Невозможно перетащить изображение в любом месте экрана и отложить изображение, где снят палец.

Я пробовал много разных методов, но всегда компилировал ошибки. Если посмотреть на мой код, может ли кто-нибудь рекомендовать простой и простой способ разместить изображение в ACTION_DRAG_ENDED (имейте в виду, что я новичок)

Вот мой код Java:

public class MainActivity extends Activity {
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
}

boolean okToDrop;

/** Called when the activity is first created. */
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    findViewById(R.id.oval).setOnTouchListener(new theTouchListener());
    findViewById(R.id.square).setOnTouchListener(new theTouchListener());
    findViewById(R.id.robot).setOnTouchListener(new theTouchListener());
    findViewById(R.id.oval).setOnDragListener(new theDragListener());
    findViewById(R.id.square).setOnDragListener(new theDragListener());
    findViewById(R.id.robot).setOnDragListener(new theDragListener());
}

private final class theTouchListener implements OnTouchListener {
    public boolean onTouch(View view, MotionEvent motionEvent) {
        if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
            ClipData data = ClipData.newPlainText("", "");
            DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(
                    view);
            view.startDrag(data, shadowBuilder, view, 0);
            view.setVisibility(View.VISIBLE);
            return true;
        } else {
            return false;
        }
    }
}

class theDragListener implements OnDragListener {
    @Override
    public boolean onDrag(View view, DragEvent dragEvent) {
        int dragAction = dragEvent.getAction();
        View dragView = (View) dragEvent.getLocalState();
        if (dragAction == DragEvent.ACTION_DRAG_EXITED) {
            okToDrop = false;
        } else if (dragAction == DragEvent.ACTION_DRAG_ENTERED) {
            okToDrop = true;
        } else if (dragAction == DragEvent.ACTION_DRAG_ENDED) {
            if (dropEventNotHandled(dragEvent) == true) {

                // Code to generate image goes here ***********************

                Context context = getApplicationContext();
                CharSequence text = "Action Dropped Not In Box!";
                int duration = Toast.LENGTH_SHORT;
                Toast toast = Toast.makeText(context, text, duration);
                toast.show();

                dragView.setVisibility(View.VISIBLE);
            }
        } else if (dragAction == DragEvent.ACTION_DROP && okToDrop) {
            ImageView i = (ImageView) findViewById(R.id.square);
            i.setImageResource(R.drawable.oval);

            dragView.setVisibility(View.INVISIBLE);

            Context context = getApplicationContext();
            CharSequence text = "Action Resulted In It Being Dropped In The Box";
            int duration = Toast.LENGTH_SHORT;
            Toast toast = Toast.makeText(context, text, duration);
            toast.show();

        }
        return true;
    }

    private boolean dropEventNotHandled(DragEvent dragEvent) {
        return !dragEvent.getResult();
    }

}

И мой xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <ImageView
        android:id="@+id/square"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:src="@drawable/square_box" />

    <ImageView
        android:id="@+id/oval"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="58dp"
        android:layout_marginTop="58dp"
        android:src="@drawable/oval" />

    <ImageView
        android:id="@+id/robot"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/oval"
        android:layout_below="@+id/square"
        android:layout_marginTop="70dp"
        android:src="@drawable/ic_launcher" />

</RelativeLayout>

Ответ 1

Хотя я не уверен, что моя реализация - лучший способ пройти, она работает.

Добавьте этих участников в свой MainActivity:

View root; // references root activity view
float dropX, dropY; // records position of where finger was lifted on the root

В вашем onCreate():

root = findViewById(android.R.id.content); // get reference to root
// add a Draglistener to your root view
root.setOnDragListener(new OnDragListener() {
    @Override
    public boolean onDrag(View v, DragEvent event) {
        int action = event.getAction();
        if(action == DragEvent.ACTION_DROP) {
            // record position of finger lift
            dropX = event.getX();
            dropY = event.getY();
        }
        return false;
    }
});

Наконец, поместите эти строки под // Code to generate image goes here:

dragView.setX(dropX - dragView.getWidth() / 2);
dragView.setY(dropY - dragView.getHeight() / 2);

Надеюсь, что это поможет.

Ответ 2

OK! Таким образом, ваша проблема заключается не в использовании одного и того же прослушивателя.

findViewById(R.id.oval).setOnDragListener(new theDragListener());

должен быть

theDragListener draglistener = new theDragListener();
findViewById(R.id.oval).setOnDragListener(draglistener);