Since PopupWindow
just adds a View
to WindowManager
you can use updateViewLayout (View view, ViewGroup.LayoutParams params)
to update the LayoutParams
of your PopupWindow
's contentView
after calling show..().
Setting the window flag FLAG_DIM_BEHIND
will dimm everything behind the window. Use dimAmount
to control the amount of dim (1.0 for completely opaque to 0.0 for no dim).
Keep in mind that if you set a background to your PopupWindow
it will put your contentView
into a container, which means you need to update it's parent.
With background:
PopupWindow popup = new PopupWindow(contentView, width, height);
popup.setBackgroundDrawable(background);
popup.showAsDropDown(anchor);
View container = (View) popup.getContentView().getParent();
WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams p = (WindowManager.LayoutParams) container.getLayoutParams();
// add flag
p.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
p.dimAmount = 0.3f;
wm.updateViewLayout(container, p);
Without background:
PopupWindow popup = new PopupWindow(contentView, width, height);
popup.setBackgroundDrawable(null);
popup.showAsDropDown(anchor);
WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams p = (WindowManager.LayoutParams) contentView.getLayoutParams();
// add flag
p.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
p.dimAmount = 0.3f;
wm.updateViewLayout(contentView, p);
Marshmallow Update:
On M PopupWindow wraps the contentView inside a FrameLayout called mDecorView. If you dig into the PopupWindow source you will find something like createDecorView(View contentView)
.The main purpose of mDecorView is to handle event dispatch and content transitions, which are new to M. This means we need to add one more .getParent() to access the container.
With background that would require a change to something like:
View container = (View) popup.getContentView().getParent().getParent();
Better alternative for API 18+
A less hacky solution using ViewGroupOverlay
:
1) Get a hold of the desired root layout
ViewGroup root = (ViewGroup) getWindow().getDecorView().getRootView();
2) Call applyDim(root, 0.5f);
or clearDim()
public static void applyDim(@NonNull ViewGroup parent, float dimAmount){
Drawable dim = new ColorDrawable(Color.BLACK);
dim.setBounds(0, 0, parent.getWidth(), parent.getHeight());
dim.setAlpha((int) (255 * dimAmount));
ViewGroupOverlay overlay = parent.getOverlay();
overlay.add(dim);
}
public static void clearDim(@NonNull ViewGroup parent) {
ViewGroupOverlay overlay = parent.getOverlay();
overlay.clear();
}