PopupWindow在Android7.0和7.1系统上显示位置不正确的问题解决

前言

今天做项目需要用到PopupWindow,但发现其显示的位置在Android7.0以下系统正常,在7.0和7.1系统显示不正常,点击“打开POP”按钮效果对比如下:

4.1系统


7.0系统


7.1系统


代码如下:

public class MainActivity extends AppCompatActivity {

    private LinearLayout popupDisplay;
    private PopupWindow popupWindow;
    private Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        popupDisplay = (LinearLayout) UiUtil.inflate((R.layout.popup));
        popupWindow = new PopupWindow(popupDisplay, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, true);
        popupWindow.setTouchable(true);
        popupWindow.setOutsideTouchable(true);
        popupWindow.setBackgroundDrawable(new BitmapDrawable(getResources(), (Bitmap) null));

        button = (Button) findViewById(R.id.btn);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                popupWindow.showAsDropDown(button);
            }
        });
    }
}

原因

详细原因请移步:PopupWindow 在 Android N(7.0) 的兼容性问题

解决

看了许多关于PopupWindow的bug的相关文章,分享如下

方案一:

自定义一个类继承PopupWindow,重写构造方法和需要用到的showAsDropDown()方法

public class SFPopupWindow extends PopupWindow {

    public SFPopupWindow(Context context) {
        super(context, null);
    }

    @Override
    public void showAsDropDown(View anchor) {
        if (Build.VERSION.SDK_INT == 24) {
            Rect rect = new Rect();
            anchor.getGlobalVisibleRect(rect);
            int h = anchor.getResources().getDisplayMetrics().heightPixels - rect.bottom;
            setHeight(h);
        }
        super.showAsDropDown(anchor);
    }
}
参考链接: http://blog.csdn.net/ithouse/article/details/56853948
方案二:

直接在需要显示的地方判断显示的方式

if (Build.VERSION.SDK_INT == 24) {
    int[] a = new int[2];
    m.get().getLocationInWindow(a);
    popupWindow.showAtLocation(getWindow().getDecorView(), Gravity.NO_GRAVITY, 0, a[1]);
    popupWindow.update();
} else {
    popupWindow.showAsDropDown(v, 0, -Utils.dip2px(46));
}
参考链接: http://blog.csdn.net/m190607070/article/details/58618662

方案三:

使用showAtLocation()显示

Android 7.0之前,在指定位置弹出popupwindow可以用showAsDropDown(View anchor, int xoff, int yoff),showAtLocation(View parent, int gravity, int x, int y)。但在android 7.0上,用showAsDropDown()在popupwindow为全屏时,会有弹出位置异常情况,需用showAtLocation()才能正常显示:

if (Build.VERSION.SDK_INT < 24)
        {
            dropListPopupWindow.showAsDropDown(this, 0, 5);
        }
        else
        {
            // 适配 android 7.0
            int[] location = new int[2];
            getLocationOnScreen(location);
            int x = location[0];
            int y = location[1];
            Log.e(getClass().getSimpleName(), "x : " + x + ", y : " + y);
            dropListPopupWindow.showAtLocation(this, Gravity.NO_GRAVITY, 0, y + getHeight() + 5);
        }
参考链接: http://blog.csdn.net/dxxs19/article/details/53572833

通过上述方案修正后,在7.1上测试如图



  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值