I have a menu icon in my application. When I drag and drop something on it, it will show a popup. I need to extend my drag and drop to this PopupWindow
.
I am doing this as below.
Created a 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 the 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;
}
});
Below video shows what I want to achieve.
But the popupView is not responding to any drag events. I also tried using the DialogFragment
, but it didn't help either.
Any help is appreciated.
Thanks in advance.
PopupWindow
will add the View
on WindowManager
instance, and not to the current layout. Whereas in the docs it is specified:
The system sends a drag event with action type ACTION_DRAG_STARTED to the drag event listeners for all the View objects in the current layout.
Pay attention to bolded "in the current layout". The content view of PopupWindow
is not considered to be in the current layout, that's why those events are not dispatched to PopupWindow
's content view.
As a workaround you can add a View
with same coordinates to the current layout, which will act as a ghost of PopupWindow
, and listen for drag events for this View
.
Add the ghost view to the layout:
<include android:id="@+id/ghost"
layout="@layout/layout_popup"/>
Setup 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;
}
});
}
We do not want ghost view to be visible, that's why we set it's alpha to zero.
Then we setup the PopupWindow
having anchor 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();
}
We need to perform setTouchable(false)
, otherwise PopupWindow
will consume touch events. Also, we set ghost view's location exactly at the position where PopupWindow
will be displayed.
Then we show and dismiss PopupWindow
on appropriate drag 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;
}
});
A pull request is opened in your repo with abovementioned functionality.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With