Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I drag and drop with multiple activities?

I used the Service call to create a Floating Window that floats over all other views/activities. This window has its own Activity and is different from Dialog.

Now i want to add a Drag&Drop action to this window, for example if you long click an ImageView in the Floating Window, you can Drag and Drop it into another Activity(or base Activity). I've been tried to use OnLongClickListener to trigger Drag event, and added OnDragListener to catch the Drop event. Here's what i have so far :

public class MyFloatableActivity extends FloatActivity {
private ImageView mImg;

private MyDragEventListener mDragListen;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.float_activity));

    // This imageView is for Drag&Drop test
    mImg = (ImageView)findViewById(R.id.drag_img));
    mImg.setOnLongClickListener(new ImageView.OnLongClickListener() {

        @Override
        public boolean onLongClick(View v) {
            ClipData dragData = ClipData.newPlainText("dragtext", "dragtext");

            v.startDrag(dragData, new View.DragShadowBuilder(v), null, 0);
            return false;
        }

    });

    mImg.setOnDragListener(mDragListen);

    switchToFloat(); // Make this activity to float
}

MyDragEventListener class is :

public class MyDragEventListener implements View.OnDragListener {

private ClipData mDragData;

@Override
public boolean onDrag(View v, DragEvent event) {
    final int action = event.getAction();
    ImageView img;

    if(v instanceof ImageView) {
        img = (ImageView)v;
    } else{
        return false;
    }

    switch(action) {
        case DragEvent.ACTION_DRAG_STARTED:
            if(event.getClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) {
                Log.d("DDD", "Drag started!!!");
                return true;
            }else {
                return false;
            }
        case DragEvent.ACTION_DRAG_ENTERED:
            Log.d("DDD", "Entered!!!");
        case DragEvent.ACTION_DRAG_LOCATION:
        case DragEvent.ACTION_DRAG_EXITED:
            return true;
        case DragEvent.ACTION_DRAG_ENDED:
        case DragEvent.ACTION_DROP:
            Log.d("DDD", "Action drop!!!");
            return true;
    }
    return true;
}

The reason i implemented OnDragListener is to listen ACTION_DROP event in base Activity when ImageView is dropped. This allows me to determine whether the ImageView was dropped on the destination image, or the layout. Here's my base Activity :

public class DragAndDropDemo extends Activity {

private ImageView mImg;

private MyDragEventListener mDragListen;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.drag_and_drop);

    //findViewById(R.id.drag_layout).setOnDragListener(mDragListen);

    mImg = (ImageView)findViewById(R.id.dest_img);

    mImg.setOnDragListener(mDragListen);
}

The problem is OnDragListener in DragAndDropDemo is not being invoked, so i couldn't catch the Drop event in my base Activity. I've seen many examples of Drag and Drop, but never got to the right solution. I'm wondering if throwing a Drag&Drop event to different Activity in Android is possible. If Android could do it, what would it be?

Is there anyone can help?

like image 898
Nari Kim Shin Avatar asked Nov 12 '22 05:11

Nari Kim Shin


1 Answers

I found the solution by myself. I integrated OnDragListener into MyFloatableActivity, and send intent to DragAndDropDemo activity to receive intents whenever a drop event occurs.

So here's my code.

public class MyFloatableActivity extends FloatActivity {
...

@Override
protected void onCreate(Bundle savedInstanceState) {
...

    mImg.setOnDragListener(new View.OnDragListener() {

        @Override
        public boolean onDrag(View v, DragEvent event) {
            switch (event.getAction()) {
                case DragEvent.ACTION_DRAG_STARTED:
                    if (event.getClipDescription().hasMimeType(
                            ClipDescription.MIMETYPE_TEXT_PLAIN)) {
                        return true;
                    } else {
                        return false;
                    }
                case DragEvent.ACTION_DRAG_ENTERED:
                case DragEvent.ACTION_DRAG_LOCATION:
                case DragEvent.ACTION_DRAG_EXITED:
                    return true;
                case DragEvent.ACTION_DRAG_ENDED:
                case DragEvent.ACTION_DROP:
                    Intent intent = new Intent();
                    intent.setAction("com.test.DragAndDrop");
                    intent.putExtra("Drop", 0);
                    sendBroadcast(intent);
                    return true;

            }
            return false;
        }

    });
...
}

and in DragAndDropDemo,

public class DragAndDropDemo extends Activity {
...
@Override
protected void onResume() {
    super.onResume();
    IntentFilter filter = new IntentFilter();
    filter.addAction("com.test.DragAndDrop");
    registerReceiver(mBR, filter);
}

@Override
protected void onPause() {
    super.onPause();
    unregisterReceiver(mBR);
}

BroadcastReceiver mBR = new BroadcastReceiver() {

    @Override
    public void onReceive(Context context, Intent intent) {
        int flag = intent.getIntExtra("Drop", 0);
        switch (flag) {
            case 0:
                mText.setText("dropped!");
                mImg.setImageResource(R.drawable.icon_argentina);
                break;
        }
    }

};
}
like image 55
Nari Kim Shin Avatar answered Nov 14 '22 23:11

Nari Kim Shin