PopupWindow显示位置错乱,真正的终极方案。

测试小姐姐在华为手机上 PopupWindow弹出位置 直接置顶了,但是我的开发机(小米9)却按照代码的意志显示在titleBar之下。

效果类似这样:
在这里插入图片描述
谷歌一把 ,各种吐槽该问题。

大神们的主流解决方案,主要分两种,
①重写showAsDropDown(),以24为界限,区别对待;
②调用show的时候,SDK>24的时用showAtLocation()替代showAsDropDown();

我先把大婶们的各类终极版的方案代码贴出来:

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

或者

if (Build.VERSION.SDK_INT < 24) {
            popupWindow.showAsDropDown(anchor);
        } else {
            int[] location = new int[2];
            anchor.getLocationOnScreen(location);
            int y = location[1];
            popupWindow.showAtLocation(anchor, Gravity.NO_GRAVITY, 0, y + anchor.getHeight());
        }

各种尝试,修改,然并卵,统统都不管用。

要么popupWin位置被顶上去,要么阴影底部有白边,要么是虚拟键滑动隐藏时,阴影底部露出白边,虚拟键动态显示时,popupWin被顶上去。各种终极版的方案,并未终结该问题。

显然是popupWin高度计算出问题了,不同手机现象不一,又是让人头大且脱发的适配问题,怎么办呢?
在这里插入图片描述
话不多说,直奔主题,我是如何解决的?

项目需求是要求上面是筛选弹窗,下层是列表,那么列表RecyclerView怎么做到不白边的?已知RecyclerView高度MATCH_PARENT,且PopupWin与背景RecyclerView等高,那我直接把RecyclerView高度设置给PopupWindow就好了。试了一下,果然完美终结该问题。

请看在华为荣耀8.安卓8.0系统上测试效果图:(请忽略该app是啥,这个不重要)

在这里插入图片描述

具体实现步骤

代码思路:
1.在popupWin.show 之前,把与她等高的View(此处指RecyclerView)高度通过setHeight赋值。等show时,高度就生效了;
2.当用户手动显示或隐藏虚拟键时候,需要根据与之等高View高度变化再次动态设置popuWin高度,此时一定是显示状态时候设置,如隐藏就不再考虑。

最重要的伪代码送上:

    private void test() {

        tvTitle.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!popupWindow.isShowing()) {
                    //设置高度,不立即生效,调用show之后,才生效
                    popupWindow.setHeight(recyclerView.getHeight());
                    popupWindow.showAsDropDown(anchor);
                } else {
                    popupWindow.dismiss();
                }
            }
        });
        //监听RecyclerView高度,动态赋值给popupWin
        recyclerView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
            @Override
            public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
                if (popupWindow.isShowing()) {
                    //设置高度并生效
                    popupWindow.update(ViewGroup.LayoutParams.MATCH_PARENT, recyclerView.getHeight());
                }
            }
        });
    }

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值