首先指定一个布局文件,根布局中使用宽高均为最大,如下
layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fff"
>
...
</RelativeLayout>
在需要创建的地方实例化布局及PopupWindow,然后显示。
View layout = getLayoutInflater().inflate(R.layout.layout, null);
final PopupWindow pop = new PopupWindow(layout,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
true);
pop.setBackgroundDrawable(new ColorDrawable(0xffffff));//支持点击Back虚拟键退出
pop.showAtLocation(findViewById(R.id.title), Gravity.NO_GRAVITY, 0, 0);
然后获取通知栏高度,在Y轴上偏移通知栏的高度即可
/**
* 获取状态通知栏高度
* @param activity
* @return
*/
public static int getStatusBarHeight(Activity activity) {
Rect frame = new Rect();
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
Log.d(TAG, "statusBarHeight:"+frame.top+"px");
return frame.top;
}
pop.showAtLocation(findViewById(R.id.title), Gravity.NO_GRAVITY, 0, getStatusBarHeight(this));
经测试发现,在SDK 4.4上先显示良好,4.1、4.2上依旧被通知栏遮挡着。。。
意外发现了SDK源代码API16与19关于showAtLocation不同之处:
关于PoupupWindow的showAtLocation中
API 19:
if (gravity == Gravity.NO_GRAVITY) {
gravity = Gravity.TOP | Gravity.START;
}
API 16:
if (gravity == Gravity.NO_GRAVITY) {
gravity = Gravity.TOP | Gravity.LEFT;
}
把Gravity.NO_GRAVITY换成Gravity.TOP|Gravity.START,现象依旧。
后来实验了 popupWindow.setClippingEnabled(false) 得以解决。
官方文档是这样解释的:
void android.widget.PopupWindow.setClippingEnabled(boolean enabled)
Allows the popup window to extend beyond the bounds of the screen. By default the window is clipped to the screen boundaries. Setting this to false will allow windows to be accurately positioned.
If the popup is showing, calling this method will take effect only the next time the popup is shown or through a manual call to one of the update() methods.
Parameters:
enabled false if the window should be allowed to extend outside of the screen
允许弹出窗口超出屏幕范围。默认情况下,窗口被夹到屏幕边界。设置为false将允许Windows精确定位。