1

Могу ли я уменьшить фон, используя PopupWindow вместо диалога? Я спрашиваю об этом, потому что я использую Dialogs, но Dialog не отображается ниже элемента, нажатого, и с PopupWindow у меня уже есть всплывающее окно, отображаемое ниже элемента.Исключить фон, используя PopupWindow в Android

ответ

10

Я использую следующий код, и он хорошо работает для меня.

public static void dimBehind(PopupWindow popupWindow) { 
    View container; 
    if (popupWindow.getBackground() == null) { 
     if (VERSION.SDK_INT >= VERSION_CODES.M){ 
      container = (View) popupWindow.getContentView().getParent(); 
     } else { 
      container = popupWindow.getContentView(); 
     } 
    } else { 
     if (VERSION.SDK_INT >= VERSION_CODES.M) { 
      container = (View) popupWindow.getContentView().getParent().getParent(); 
     } else { 
      container = (View) popupWindow.getContentView().getParent(); 
     } 
    } 
    Context context = popupWindow.getContentView().getContext(); 
    WindowManager wm = (WindowManager) context.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); 
} 

От This answer.

+0

Просмотреть контейнер = (Просмотреть) popUp.getContentView(). GetRootView(); Это работает для до и после М. Проверено в желе и зефире. – Sanju

+0

Это сбой в симуляторе Нуга: 'com.android.launcher3 W/OpenGLRenderer: Неверно названный buildLayer в представлении: ShortcutAndWidgetContainer, уничтожающий слой ...'. Во всяком случае, код просто не устраивает меня со мной, это переменное количество жестко закодированных 'getParent()' s - не кажется перспективным. – HughHughTeotl

+0

Неправильная строка. Он должен быть p.flags | = WindowManager.LayoutParams.FLAG_DIM_BEHIND; // добавляем флаг вместо вместо других. –

0

На данный момент я использую Диалог. Но если у кого-то была другая идея, пожалуйста, дайте мне знать ...

3

Решение JiaJiaGu работает, но popupWindow будет перекрываться с панелью навигации, поскольку он очищает все остальные флаги.

Так что я изменить немного здесь:

public static void dimBehind(PopupWindow popupWindow) { 
    View container; 
    if (popupWindow.getBackground() == null) { 
     if (VERSION.SDK_INT >= VERSION_CODES.M){ 
      container = (View) popupWindow.getContentView().getParent(); 
     } else { 
      container = popupWindow.getContentView(); 
     } 
    } else { 
     if (VERSION.SDK_INT >= VERSION_CODES.M) { 
      container = (View) popupWindow.getContentView().getParent().getParent(); 
     } else { 
      container = (View) popupWindow.getContentView().getParent(); 
     } 
    } 
    Context context = popupWindow.getContentView().getContext(); 
    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 
    WindowManager.LayoutParams p = (WindowManager.LayoutParams) container.getLayoutParams(); 
    p.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND; // add a flag here instead of clear others 
    p.dimAmount = 0.3f; 
    wm.updateViewLayout(container, p); 
} 

я отправляю новый ответ, потому что я не могу прокомментировать ответ JiaJiaGu в.

1

Кажется, я выяснил, как избавиться от проверки версии API. Использование container = popupWindow.getContentView().getRootView() решает проблему, однако я еще не тестировал ее для старых API. Адаптация решения Junyue Cao:

public static void dimBehind(PopupWindow popupWindow) { 
    View container = popupWindow.getContentView().getRootView(); 
    Context context = popupWindow.getContentView().getContext(); 
    WindowManager wm = (WindowManager) context.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); 
} 
Смежные вопросы