Так как PopupWindow
только добавляет View
к WindowManager
вам можно использовать updateViewLayout (View view, ViewGroup.LayoutParams params)
для обновления LayoutParams
ваших PopupWindow
«с contentView
после вызова шоу .. ().
Установка флажка окна FLAG_DIM_BEHIND
затемняет все, что находится за окном. Используется dimAmount
для управления степенью затемнения (от 1,0 для полной непрозрачности до 0,0 для отсутствия затемнения).
Имейте в виду, что если вы установите фон для своего, PopupWindow
он поместит вас contentView
в контейнер, что означает, что вам нужно обновить его родительский.
С фоном:
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);
Без фона:
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:
В M PopupWindow оборачивает contentView внутри FrameLayout с именем mDecorView. Если вы покопаетесь в источнике PopupWindow, вы найдете что-то вроде createDecorView(View contentView)
. Основная цель mDecorView - обрабатывать отправку событий и переходы контента, которые являются новыми для M. Это означает, что нам нужно добавить еще один .getParent () для доступа к контейнеру.
С фоном, который потребует изменения чего-то вроде:
View container = (View) popup.getContentView().getParent().getParent();
Лучшая альтернатива API 18+
Менее хакерское решение, использующее ViewGroupOverlay
:
1) Получите желаемый корневой макет
ViewGroup root = (ViewGroup) getWindow().getDecorView().getRootView();
2) Позвоните applyDim(root, 0.5f);
или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();
}