近期有一个类似咸鱼发布功能的需求,这里使用了PopupWindow去实现所有的效果,但是在UI走查阶段,OPPO的一款手机无法全屏,状态栏没有遮盖,此处记录解决过程。
部分初始重要代码:
public class MyPopWindow extends PopupWindow implements View.OnClickListener {
private View rootView;
private RelativeLayout contentView;
private Activity mContext;
public MyPopWindow(Activity context) {
this.mContext = context;
}
@RequiresApi(api = Build.VERSION_CODES.CUPCAKE)
public void showMoreWindow(View anchor) {
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rootView = inflater.inflate(R.layout.dialog_centre, null);
initView();
showAtLocation(anchor, Gravity.BOTTOM, 0, 0);
}
private void initView() {
setContentView(rootView);
setWidth(mContext.getWindowManager().getDefaultDisplay().getWidth());
setHeight(mContext.getWindowManager().getDefaultDisplay().getHeight());
setBackgroundDrawable(new BitmapDrawable());
setFocusable(true);
}
}
方式一:
添加以下属性会解决大部分机型问题包括Build.VERSION.SDK_INT大于21的:
setClippingEnabled(false);
但是此时OPPO机型 Build.VERSION.SDK_INT=27却还是存在状态栏未遮盖问题。
方式二:
添加以下方法完美解决了遗留的问题,nice!
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
try {
Field mLayoutInScreen = PopupWindow.class.getDeclaredField("mLayoutInScreen");
mLayoutInScreen.setAccessible(true);
mLayoutInScreen.set(this, true);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
总结:
第一种解决方式官方注释是允许弹出窗口超出屏幕边界。默认情况下,窗口被剪切到屏幕边界。将此设置为false将允许窗口为准确定位。这个时候我去设置它的宽高为屏幕宽高通常是可行的。
第二种解决方式是判断当Build.VERSION.SDK_INT大于21时对其做特殊处理,也就是通过反射获得mLayoutInScreen属性,并且设置其值为true,官方解释允许弹窗强制去标记,覆盖默认行为。这将导致弹出窗口被定位在绝对屏幕坐标。启用true,表示弹出窗口应该始终位于屏幕坐标中。其目的和方式一类似。