Dado que PopupWindow
sólo se suma una View
que WindowManager
se puede utilizar updateViewLayout (View view, ViewGroup.LayoutParams params)
para actualizar el LayoutParams
de sus PopupWindow
's contentView
después de llamar espectáculo .. ().
Establecer la bandera de la ventana FLAG_DIM_BEHIND
atenuará todo lo que se encuentra detrás de la ventana. Úselo dimAmount
para 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, PopupWindow
lo colocará contentView
en 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();
}