Ponieważ PopupWindowpo prostu dodaje Viewsię do WindowManagerwas może wykorzystać updateViewLayout (View view, ViewGroup.LayoutParams params)do zaktualizowania LayoutParamsswoich PopupWindow„s contentViewpo wywołaniu pokaz .. ().
Ustawienie flagi okna FLAG_DIM_BEHINDspowoduje przyciemnienie wszystkiego za oknem. Służy dimAmountdo kontrolowania ilości przyciemnienia (od 1,0 dla całkowitego nieprzezroczystości do 0,0 dla braku przyciemnienia).
Pamiętaj, że jeśli ustawisz tło na swoje PopupWindow, umieści contentViewje w kontenerze, co oznacza, że musisz zaktualizować jego rodzica.
Z tłem:
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);
Bez tła:
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);
Aktualizacja Marshmallow:
W M PopupWindow otacza contentView wewnątrz FrameLayout o nazwie mDecorView. Jeśli zagłębisz się w źródło PopupWindow, znajdziesz coś w rodzaju createDecorView(View contentView).Głównym celem mDecorView jest obsługa wysyłania zdarzeń i przejść treści, które są nowe dla M. Oznacza to, że musimy dodać jeszcze jedną .getParent (), aby uzyskać dostęp do kontenera.
Z tłem, które wymagałoby zmiany na coś takiego:
View container = (View) popup.getContentView().getParent().getParent();
Lepsza alternatywa dla API 18+
Mniej hakerskie rozwiązanie wykorzystujące ViewGroupOverlay:
1) Zdobądź pożądany układ katalogu głównego
ViewGroup root = (ViewGroup) getWindow().getDecorView().getRootView();
2) Zadzwoń applyDim(root, 0.5f);lubclearDim()
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();
}