在弹出PopupWindow的时候,设置Window的alpha(透明度)和dim(暗淡值)两个值。
final Window window = getWindow();
final WindowManager.LayoutParams params = window.getAttributes();
window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
params.dimAmount = 0.7f;
params.alpha = 0.7f;
window.setAttributes(params);
popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
@Override
public void onDismiss() {
params.dimAmount = 1.0f;
params.alpha = 1.0f;
window.setAttributes(params);
}
});
效果如下图所示:
设置PoppupWindow在具体位置,可以调用popupWindow.showAtLocation(View, int, int, int)方法。
/**
*
* Display the content view in a popup window at the specified location. If the popup window
* cannot fit on screen, it will be clipped. See {@link android.view.WindowManager.LayoutParams}
* for more information on how gravity and the x and y parameters are related. Specifying
* a gravity of {@link android.view.Gravity#NO_GRAVITY} is similar to specifying
* Gravity.LEFT | Gravity.TOP
.
*
*
* @param parent a parent view to get the {@link android.view.View#getWindowToken()} token from
* @param gravity the gravity which controls the placement of the popup window
* @param x the popup's x location offset
* @param y the popup's y location offset
*/
public void showAtLocation(View parent, int gravity, int x, int y) {
showAtLocation(parent.getWindowToken(), gravity, x, y);
}
其中,参数parent为PopupWindow关联的View;参数gravity为PopupWindow的位置(居左,居中,居右等);参数x为PopupWindow的x坐标偏移量;参数y为PopupWindow的y坐标偏移量。
在上面图中,PopupWindow显示在Button的左边位置,并且与Button对齐,具体代码为:
int[] location = new int[2];
button.getLocationInWindow(location);
popupWindow.showAtLocation(button, Gravity.NO_GRAVITY, location[0] - contentView.getWidth(), location[1] - contentView.getMeasuredHeight() / 2 + button.getHeight() / 2);
注意:当contentView的宽或高为wrap_content时,要先测量contentView的宽高。测量方法如下:
contentView.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
实际上调用measure()方法时,会去调用onMeasure()方法,然后测量出View的大小。
public final void measure(int widthMeasureSpec, int heightMeasureSpec){}
参数widthMeasureSpec:表示父容器强加给的水平空间
参数heightMeasureSpec:表示父容器强加给的垂直空间
关于View.MeasureSpec.makeMeasureSpec(int, int)方法:
public static int makeMeasureSpec(@IntRange(from = 0, to = (1 << MeasureSpec.MODE_SHIFT) - 1) int size,
@MeasureSpecMode int mode) {}
参数size:是指在某种测量模式的规格大小
参数mode:是指在测量模式
另外,模式只有三种值:
在使用动画时,如果PopupWindow从底部弹出:
popupWindow.showAtLocation(v.getRootView(), Gravity.BOTTOM, 0, 0);
那么在系统5.0以上,会出现在NavigationBar下面弹出或者被NavigationBar遮挡问题。如下图所示:
针对这个问题有如下解决方案:
在values-21/style.xml中的主题中添加:
<item name="android:windowDrawsSystemBarBackgrounds">falseitem>
这个属性指示这个窗口是否负责绘制系统bar的背景。