Dado que PopupWindowsólo se suma una Viewque WindowManagerse puede utilizar updateViewLayout (View view, ViewGroup.LayoutParams params)para actualizar el LayoutParamsde sus PopupWindow's contentViewdespués de llamar espectáculo .. ().
Establecer la bandera de la ventana FLAG_DIM_BEHINDatenuará todo lo que se encuentra detrás de la ventana. Úselo dimAmountpara controlar la cantidad de atenuación (1.0 para completamente opaco a 0.0 para no atenuar).
Tenga en cuenta que si establece un fondo para su, PopupWindowlo colocará contentViewen un contenedor, lo que significa que debe actualizar su padre.
Con antecedentes:
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();
p.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
p.dimAmount = 0.3f;
wm.updateViewLayout(container, p);
Sin fondo:
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();
p.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
p.dimAmount = 0.3f;
wm.updateViewLayout(contentView, p);
Actualización de Marshmallow:
En M, PopupWindow envuelve el contentView dentro de un FrameLayout llamado mDecorView. Si profundiza en la fuente de PopupWindow, encontrará algo como createDecorView(View contentView). El propósito principal de mDecorView es manejar el envío de eventos y las transiciones de contenido, que son nuevas para M. Esto significa que debemos agregar un .getParent () más para acceder al contenedor.
Con antecedentes que requerirían un cambio a algo como:
View container = (View) popup.getContentView().getParent().getParent();
Mejor alternativa para API 18+
Una solución menos hacky usando ViewGroupOverlay:
1) Obtenga el diseño raíz deseado
ViewGroup root = (ViewGroup) getWindow().getDecorView().getRootView();
2) Llame applyDim(root, 0.5f);oclearDim()
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();
}