1

我可以使用PopupWindow而不是对话框调暗背景吗?我在问这是因为我使用的是对话框,但对话框不显示在单击的项目下方,而且使用PopupWindow,我已经在项目下方显示了弹出窗口。在Android中使用PopupWindow调暗背景

回答

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(); 这适用于前和后M.检入果冻豆和棉花糖。 – Sanju

+0

这在Nougat模拟器中崩溃:'com.android.launcher3 W/OpenGLRenderer:错误地在View上调用buildLayer:ShortcutAndWidgetContainer,销毁图层...'。无论如何,代码并不能很好地适应我,可变数量的硬编码getParent() - 似乎并不是未来的保证。 – 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进行测试。改编曹军岳的解决方案:

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); 
}