PopUpWindow在Android7.0及以上位置和阴影显示问题

1、PopupWindow的位置显示问题

项目时发现Popupwindow在7.0及以上的设备上显示位置异常,6.0上及以下却没有问题:
解决方式:调用Popupwindow的showasdrop方法 代码如下

  /**
 * 适配7.0系统显示弹窗问题
  * @param window
 * @param parent
 * @param offsetY
  */
  public static voidadapterApiV24ForShowAsDropDown(PopupWindow window, View parent, int     offsetY) {

 if (null == window) {
      return;
  }

  if (null == parent) {

  return;

  }

  if(Build.VERSION.SDK_INT >= 24){

  Rect visibleFrame = new Rect();

  parent.getGlobalVisibleRect(visibleFrame);

 int height =parent.getResources().getDisplayMetrics().heightPixels - visibleFrame.bottom 
 +Math.abs(offsetY);

  window.setHeight(height);

 }

window.showAsDropDown(parent, 0, offsetY);

   }

代码难点解析
parent.getGlobalVisibleRect(visibleFrame);这里主要是获取传入的view 在屏幕上的位置
visibleFrame.bottom就是获取该view在屏幕的y的高度

Math.abs(offsetY) 这个是popupWindow显示的位置y轴的偏移量

int height = parent.getResources().getDisplayMetrics().heightPixels - visibleFrame.bottom + Math.abs(offsetY);这里是算出屏幕分辨率的高度-该view在屏幕上的高度+Y轴偏移量

window.setHeight(height);这里就是给popupWindow重新设置一下高度 一定要设置 否则就不起作用

window.showAsDropDown(parent, 0, offsetY);
这一句就很简单了 你懂得 不懂的就去百度一下showAsDropDown跟showAtLocation的区别

2、PopupWindow的阴影覆盖问题

android7.0以上的小米手机和华为手机下面状态栏隐藏的时候会出现阴影没有覆盖到最底部的情况(前提是popupWindow往下面弹出) 看图说话 小米全面屏出现的问题

device-2018-08-01-115629.png

解决办法 直接上代码

/**
 * 通过判断是否有导航栏 适配7.0以上系统显示弹窗问题
 * 主要是解决阴影没有遮住下面的TabHost的问题
 *
 * @param window
 * @param parent
 * @param offsetY
 */
public static void adapterApiV24ForShowAsDropDown(PopupWindow window, View parent, int   offsetY) {
if (null == window) {
    return;
}
if (null == parent) {
    return;
}
if (Build.VERSION.SDK_INT >= 24) {
    Rect visibleFrame = new Rect();
    parent.getGlobalVisibleRect(visibleFrame);
    int height;
    /**
     * 判断是否有导航栏
     */
    if (BarUtils.isShowNavBar(window.getContentView().getContext())) {
        height = parent.getResources().getDisplayMetrics().heightPixels - visibleFrame.bottom + Math.abs(offsetY);
    } else {
        /**
         * 获取物理真实高度 才能在android 7.0以上遮住下面的TabHost
         */
        height = WindowDispaly.getRealHeight() - visibleFrame.bottom + Math.abs(offsetY);
    }
    window.setHeight(height);
}
window.showAsDropDown(parent, 0, offsetY);
}

判断是否有导航栏的方法 BarUtils类 (该方法可以基本适配所有机型 判断是否显示了导航栏 后续有文章专门说明我的思路)

/**
 * 判断是否显示了导航栏
 * (说明这里的context 一定要是activity的context 否则类型转换失败)
 *
 * @param context
 * @return
 */
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();
/**
 * 获取状态栏高度
 */
int statuBarHeight = WindowDispaly.getStatusBarHeight();
/**
 * 屏幕物理高度 减去 状态栏高度
 */
int remainHeight = WindowDispaly.getRealHeight() - statuBarHeight;
/**
 * 剩余高度跟应用区域高度相等 说明导航栏没有显示 否则相反
 */
if (activityHeight == remainHeight) {
    return false;
} else {
    return true;
}

}

获取真实屏幕高度比如我的手机是小米6X 设置中显示 分辨率是2160X1080 2160就是真实屏幕高度(包括了状态栏高度) WindowDispaly类中的代码如下

/**
 * 获取真实屏幕高度
 *
 * @return
 */
public static int getRealHeight() {
if (null == wm) {
    wm = (WindowManager) BaseApplication.getContext().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;
}

/**
 * 获取状态栏高度
 *
 * @return
 */
public static int getStatusBarHeight() {
    int result = 0;
    int resourceId = BaseApplication.getContext().getResources().getIdentifier("status_bar_height", "dimen", "android");
    if (resourceId > 0) {
        result = BaseApplication.getContext().getResources().getDimensionPixelSize(resourceId);
    }
    return result;
}

修改后运行效果如下图

device-2018-08-01-141758.png

3、PopupWindow的阴影没有覆盖状态栏的问题

目前测试机型也是小米6x 效果如下图

17.png

解决办法 增加一行代码就搞定

popupWindow.setClippingEnabled(false) 

原理我也没仔细研究了 给个我觉得还靠谱的博客文章
PopupWindow全屏显示

修改后的效果如下图

07.png

对PopupWindow的总结

1、对showAsDropDown跟showAtLocation方法需要熟悉以便控制PopupWindow显示的位置

2、状态栏和导航栏对PopupWindow的高度影响需要考虑

3、PopupWindow在android7.0以上有很多的适配bug(谷歌工程师的锅),所以看以后如果用到PopupWindow可以考虑用Activity替代

嘿嘿 第一次写简书文章排版不是很好看各位请见谅,如果遇到以上适配问题或者判断导航栏方法是否可见 有bug都希望各位留言 一起努力解决问题
ZFFQ(K5EV_FFXA711(G1_9K.gif
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,607评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,239评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,960评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,750评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,764评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,604评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,347评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,253评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,702评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,893评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,015评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,734评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,352评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,934评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,052评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,216评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,969评论 2 355