PopupWindow not responding to drag and drop events

I have a menu icon in the application. When I drag something onto it, it will show a popup. I need to extend my drag and drop to this PopupWindow .

I do this as shown below.

Created PopupWindow as shown

 View popupView = View.inflate(anchorView.getContext(), R.layout.layout_popup, null); PopupWindow popUpWindow = new PopupWindow(popupView, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT); 

And setting dragListener as shown

 popupView.setOnDragListener(new OnDragListener() { @Override public boolean onDrag(View view, DragEvent dragEvent) { switch (dragEvent.getAction()) { case DragEvent.ACTION_DRAG_STARTED: Log.d("Drag", "ACTION_DRAG_STARTED"); break; case DragEvent.ACTION_DRAG_ENDED: Log.d("Drag", "ACTION_DRAG_ENDED"); break; case DragEvent.ACTION_DRAG_ENTERED: Log.d("Drag", "ACTION_DRAG_ENTERED"); break; case DragEvent.ACTION_DRAG_EXITED: Log.d("Drag", "ACTION_DRAG_EXITED"); break; case DragEvent.ACTION_DROP: Log.d("Drag", "ACTION_DROP"); break; default: break; } return true; } }); 

The video below shows what I want to achieve.

enter image description here

But popupView does not respond to any drag and drop events. I also tried using DialogFragment , but that didn't help either. Any help is appreciated.

Thanks in advance.

+8
android drag-and-drop android-popupwindow
source share
1 answer

PopupWindow will add the View to the WindowManager instance , and not to the current layout. While the docs indicate:

The system sends a drag event with action type ACTION_DRAG_STARTED for drag event listeners for all View objects in the current layout .

Notice the bold " in current layout ". Viewing PopupWindow content PopupWindow not considered in the current layout, so these events are not dispatched to the PopupWindow content PopupWindow .

As a workaround, you can add a View with the same coordinates to the current layout, which will act as a ghost of PopupWindow and listen for drag and drop events for that View .


Implementation

Add a ghost view to the layout:

 <include android:id="@+id/ghost" layout="@layout/layout_popup"/> 

Customize the ghost view from onCreate() :

 private void setupGhostView() { ghost = findViewById(R.id.ghost); ghost.setAlpha(0.0f); ghost.findViewById(R.id.txt_append).setOnDragListener(new OnDragListener() { @Override public boolean onDrag(View v, DragEvent event) { if (event.getAction() == DragEvent.ACTION_DROP) { Toast.makeText(MainActivity.this, "Settings 1", Toast.LENGTH_SHORT).show(); } return true; } }); ghost.findViewById(R.id.txt_replace).setOnDragListener(new OnDragListener() { @Override public boolean onDrag(View v, DragEvent event) { if (event.getAction() == DragEvent.ACTION_DROP) { Toast.makeText(MainActivity.this, "Settings 2", Toast.LENGTH_SHORT).show(); } return true; } }); }
private void setupGhostView() { ghost = findViewById(R.id.ghost); ghost.setAlpha(0.0f); ghost.findViewById(R.id.txt_append).setOnDragListener(new OnDragListener() { @Override public boolean onDrag(View v, DragEvent event) { if (event.getAction() == DragEvent.ACTION_DROP) { Toast.makeText(MainActivity.this, "Settings 1", Toast.LENGTH_SHORT).show(); } return true; } }); ghost.findViewById(R.id.txt_replace).setOnDragListener(new OnDragListener() { @Override public boolean onDrag(View v, DragEvent event) { if (event.getAction() == DragEvent.ACTION_DROP) { Toast.makeText(MainActivity.this, "Settings 2", Toast.LENGTH_SHORT).show(); } return true; } }); } 

We do not make the ghost visible, so we set it to zero.

Then we set up PopupWindow with a PopupWindow view:

 private void preparePopup(View anchorView) { final View popupView = View.inflate(anchorView.getContext(), R.layout.layout_popup, null); popupView.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)); popupWindow = new PopupWindow(popupView, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT); popupWindow.setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT)); popupWindow.setTouchable(false); FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( popupView.getMeasuredWidth(), popupView.getMeasuredHeight()); params.gravity = Gravity.END; ghost.setLayoutParams(params); ghost.invalidate(); ghost.requestLayout(); }
private void preparePopup(View anchorView) { final View popupView = View.inflate(anchorView.getContext(), R.layout.layout_popup, null); popupView.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)); popupWindow = new PopupWindow(popupView, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT); popupWindow.setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT)); popupWindow.setTouchable(false); FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( popupView.getMeasuredWidth(), popupView.getMeasuredHeight()); params.gravity = Gravity.END; ghost.setLayoutParams(params); ghost.invalidate(); ghost.requestLayout(); } 

We need to execute setTouchable(false) , otherwise PopupWindow will consume touch events. In addition, we set the ghost viewing location to exactly where PopupWindow will be displayed.

Then we show and reject the PopupWindow on the corresponding drag and drop events:

 menuView.setOnDragListener(new OnDragListener() { @Override public boolean onDrag(View v, DragEvent event) { int dragEvent = event.getAction(); switch (dragEvent) { case DragEvent.ACTION_DRAG_ENTERED: popupWindow.showAsDropDown(anchorView); break; case DragEvent.ACTION_DRAG_ENDED: popupWindow.dismiss(); break; } return true; } });
menuView.setOnDragListener(new OnDragListener() { @Override public boolean onDrag(View v, DragEvent event) { int dragEvent = event.getAction(); switch (dragEvent) { case DragEvent.ACTION_DRAG_ENTERED: popupWindow.showAsDropDown(anchorView); break; case DragEvent.ACTION_DRAG_ENDED: popupWindow.dismiss(); break; } return true; } }); 

Result

enter image description here

Your repo with the above functions opens a transfer request .

+2
source share

All Articles