Поскольку PopupWindow
просто добавляет View
к WindowManager
, вы можете использовать updateViewLayout (View view, ViewGroup.LayoutParams params)
для обновления LayoutParams
ваших PopupWindow
* contentView
после вызова show .. ().
Установка флажка окна 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);
Обновление "Зефир":
В 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();
}