razerdp/BasePopup

三星S10+手势导航栏,Popup底部显示不全

Closed this issue · 45 comments

提issue前请去WIKI#常见问题找找相关问题,避免重复提问

提issue前请务必参考以下格式填写,否则该问题优先级将会降低

  • 系统版本:三星S10+,android 9.0
  • 库版本:2.1.9
  • 问题描述/重现步骤:手机是三星S10+,让popup在手机最底下显示,导航栏切换成手势的话popup下面不铺满,看代码和截图
  • 问题代码/截图:
    QQ截图20190508132427

这样正常:
Screenshot_20190508-133448_R-ONE

这样BUG:
Screenshot_20190508-131216_R-ONE(1)

  • 报错信息:没有

你好,不使用showPopupWindow(x,y)方法试试?因为指定了位置的话不排除跟您的screenHeight获取高度不对有关,请设置gravity=bottom并直接调用showPopupWindow()无参方法,basepopup内部针对屏幕高度有过适配

screenHeight其实就是库的这个方法,因为是kotlin所以直接是screenHeight
/**
* 获取屏幕高度(px)
*/
public int getScreenHeight() {
return PopupUiUtils.getScreenHeightCompat(getContext());
}
QQ截图20190509093526
结果还是不不行,底部显示不全

貌似三星这种手势导航栏都不能正确拿到屏幕高,我用其他Popup库是获取anchorView的实际测量高度作为锚点,然后对齐底部向上显示的,

手机中存在手势导航栏时,从底部弹出,软键盘与弹窗之间会有导航栏的高度

手势导航栏判断难度在于各家都有各自的手势导航栏,比如小米可以通过某个参数判定,但是其他的手机呢,,,市面上安卓的ROOM太多,我没法涵盖所有的,所以在我找到比较通用的解决方案之前,可能对于手势导航栏这一块有点难适配。

@razerdp https://developer.android.com/training/system-ui/navigation#java
不妨试试这个 改好的话 更新一下哈 谢谢

@xiaozhao0331 跟这里无关哦,目前candy版本提供了设置蒙层的宽高方法,过渡一下。

0toN commented

1.x版本没这问题

@0toN 尝试下最新的alpha版本

0toN commented

@0toN 尝试下最新的alpha版本

嗯,我试试。不过我手机不是全面屏手机蒙层也会显示不全,另外自带的控件例如BottomSheetDialogFragment就不会有这个问题,感觉有点奇怪

@0toN ya,全面屏这个问题当时我手机也不是全面屏,所以没法测试,同时关于手机高度的获取也有一定的问题,在2.2.2的版本我针对这个情况进行了一次研究,顺道买了一台全面屏。。。现在测试机是小米的k20,目前测试正常

@CordyHo @Hyacinth-fjk @xiaozhao0331 @0toN

最新Demo已经添加对手势导航栏的测试。。。请尝试下Demo是否正常

目前添加 的手势导航栏支持:

  • 小米
  • vivo
  • 三星

device-2019-09-27-115902

三星还是不行

我直接用的最新的demo

@lovemianhuatang 你的什么机型啊。。。我找群里的人三星测试都正常。

@razerdp 三星S8 型号:SM-G9550

我的三星s8+也出现了这种问题,请问有办法解决吗

@ZHANGYU1507 我手上没有测试机,所以针对这种类型的导航栏我还真没法去好好的测试。。。

我的测试机 三星Galaxy A60,型号SM-A6060也出现了这个问题(暂时把showPopupWindow方法重写成系统自带的showAtLocation就显示正常了)
微信图片_20191230090330

基本出问题的都是三星下面有三个小条条的。。。,我猜测其实这三个小条条是存在导航栏的,只是导航栏的按钮被设置成手势?我手上没有三星机,你可以把layout inspecotr的li文件发过来看看

常见页面页和弹框的li文件
captures.zip

@weiweixiaoyi

根据你的li文件,其实基本跟我的猜测一致

首先三星的这种navigation导航栏并不是完全的隐藏了(所以算是个伪全面手势?)

所以在BasePopup中判定是存在navigationbar的,因此调用系统的api获取navigation的高度

从代码和逻辑上来看,其实并没有问题
但从表现上来看,就是这样的蛋疼的navigation导致了无法完全覆盖

系统的popupwindow之所以没问题是因为系统的popup是以window来算,而basepopup是在系统的这个window上addview进行包裹,因为很多时候系统的popup会把popup显示在导航栏上,表现上来说就是导航栏挡住了popup,因此basepopup对此进行修正。

微信截图_20191230151735

这个问题我之后尽量找些三星机子或者查查类似的异形导航栏有啥特点,如果能正确识别就可以解决这种问题了。

明白了,谢谢

public static boolean isShowNavBar(Context context) {
if (null == context) {
return false;
}
/**
* 获取应用区域高度
*/
Rect outRect1 = new Rect();
try {
((Activity) context).getWindow().getDecorView().getWindowVisibleDisplayFrame(outRect1);
} catch (ClassCastException e) {
e.printStackTrace();
return false;
}
int activityHeight = outRect1.height();

    Log.e("zrj", "状态栏高度:" + getStatusBarHeight());
    Log.e("zrj", "应用区域高度:" + activityHeight);
    Log.e("zrj", "导航栏高度:" + getNavBarHeight());
    Log.e("zrj", "屏幕物理高度:" + getRealHeight(context));
    /**
     * 屏幕物理高度 - 状态栏高度  导航栏高度 = 导航栏存在时的应用实际高度
     */
    int remainHeight = getRealHeight(context) - getStatusBarHeight() - getNavBarHeight();

    Log.e("zrj", "remainHeight:" + remainHeight);
    /**
     * 剩余高度跟应用区域高度相等 说明导航栏存在
     */
    if (activityHeight == remainHeight) {
        return true;
    } else {
        return false;
    }
}

public static int getRealHeight(Context context) {
    WindowManager wm = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE));
    Point point = new Point();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        wm.getDefaultDisplay().getRealSize(point);
    } else {
        wm.getDefaultDisplay().getSize(point);
    }
    return point.y;
}

这种判定方式曾经在basepopup用过。。。然而忘了在哪个版本就有人反馈过不适用。。于是就换了

很多弹窗库都没适配 有点无奈

@lovemianhuatang

找到了,18年12月23号,就是这种判断物理高度和应用高度的方法,后面因为issue告知部分设备不能使用因此舍弃。

https://github.com/razerdp/BasePopup/blob/aaab0bebcb63ffd311b49f9ed38b81708ac4360b/lib/src/main/java/razerdp/util/PopupUiUtils.java

什么机型有问题? 我现在就是用这个方法解决的 有点慌

@razerdp 有什么好的方案吗?

现有的方案就是比较好的方案,但无法解决三星这种“navigation实际存在”,但却是小小一点的问题,不过多数手机可以适配,原理其实是去找navigationbar这个id(以及另一个库替换的bar的id),去判断可见性来解决。

@razerdp 代码在BasePopup哪个类 我有个项目用的弹窗没有适配 我想复制过去修改判断方法

@lovemianhuatang 我刚刚重构了一波,请问可以试试下载工程并运行,然后测试一下,看看能否正常
微信截图_20200120163307

@razerdp 可以了 兄弟 稳

1

遮罩没问题了 但是弹窗距离底部有间隔

嗯,还没重构完的,只是去解决了mask的问题,。三星那个主要是他的navigation确实是存在的。。。所以layout的时候无法layout到底部

嗯 弄完可以找我测试

@lovemianhuatang

我在云真机测试情况如下,你可以更新代码再次尝试~

微信截图_20200120174451
微信截图_20200120174437

事实上,因为底部那里正是navigationbar,,,所以其实不能完全覆盖底部的,否则就是挡着navigation了

加个好友 我给你发下录频吧 QQ 2896543728

@weiweixiaoyi
@xiaozhao0331
@ZHANGYU1507
@0toN
@lovemianhuatang

该问题目前也在miui12发现

可以的话前往 #307 加入讨论

能否适配横屏输入法弹框,在MIUI12上横屏有问题。

能否适配横屏输入法弹框,在MIUI12上横屏有问题。

请看文档,输入法

请不要在已关闭的issue下提问无关问题了,这导致所有人都收到。