Android:使用PopupWindow.update( )碰到的坑
2017-01-16 20:07
453 查看
背景
前期做项目实现了一个自定义键盘的控件,主要是通过extends PopupWindow来实现,后期我会考虑把这个自定义键盘开源,敬请关注。其中用到了PopupWindow.update( )方法,在Android7.0正式发布前,即在Android7.0以下的系统上没有问题,最近Android7.0的手机已经陆续进入市场。就在这几天,有同事反应我们项目里面那个自定义键盘原来在界面底部,是正常,但是在Android7.0系统上就跑到界面顶部了,不正常了。
如下图,第1张图是不正常的,第2张图是正常的。
原因
1.自定义键盘的布局。初步从自定义键盘的布局入手,检查是否由布局引起,经过再三调试发现,布局没有问题。2.断点调试。
public void show(View parent){ if (parent != null) { mPopupWindow.showAtLocation(parent, Gravity.BOTTOM, 0, 0); } mPopupWindow.update(); }
调试这个方法,发现问题出在PopupWindow.update( )这里。
PopupWindow.update( )是做什么的呢?查看源码,系统解释是:
Updates the state of the popup window, if it is currently being displayed,from the currently set state.
中文意思:更新PopupWindow状态,如果当前已是显示状态,就从当前状态更新。
Android7.0以下的系统:
public void update() { if (!isShowing() || mContentView == null) { return; } WindowManager.LayoutParams p = (WindowManager.LayoutParams) mPopupView.getLayoutParams(); boolean update = false; final int newAnim = computeAnimationResource(); if (newAnim != p.windowAnimations) { p.windowAnimations = newAnim; update = true; } final int newFlags = computeFlags(p.flags); if (newFlags != p.flags) { p.flags = newFlags; update = true; } if (update) { setLayoutDirectionFromAnchor(); mWindowManager.updateViewLayout(mPopupView, p); } }
Android7.0系统:
public void update() { if (!isShowing() || mContentView == null) { return; } final WindowManager.LayoutParams p = (WindowManager.LayoutParams) mDecorView.getLayoutParams(); boolean update = false; final int newAnim = computeAnimationResource(); if (newAnim != p.windowAnimations) { p.windowAnimations = newAnim; update = true; } final int newFlags = computeFlags(p.flags); if (newFlags != p.flags) { p.flags = newFlags; update = true; } final int newGravity = computeGravity(); if (newGravity != p.gravity) { p.gravity = newGravity; update = true; } if (update) { setLayoutDirectionFromAnchor(); mWindowManager.updateViewLayout(mDecorView, p); } }
经过对比发现,主要区别是下面这段代码:
final int newGravity = computeGravity(); if (newGravity != p.gravity) { p.gravity = newGravity; update = true; }
接下来我们再看computeGravity()这个方法
private int computeGravity() { int gravity = Gravity.START | Gravity.TOP; if (mClipToScreen || mClippingEnabled) { gravity |= Gravity.DISPLAY_CLIP_VERTICAL; } return gravity; }
在computeGravity()这个方法可以看出,在Android7.0系统上,调用PopupWindow.update( )方法会导致PopupWindow的位置出现在界面顶部,而不是我们自己定义的位置,如:界面底部。
解决办法
PopupWindow.update( )在自定义键盘根本没有起到实质作用,注释掉即可。如下:public void show(View parent){ if (parent != null) { mPopupWindow.showAtLocation(parent, Gravity.BOTTOM, 0, 0); } // mPopupWindow.update(); //因android7.0此方法有改动,不适用android7.0系统以下使用,所以不再调用此方法 }
相关文章推荐
- android之PopUpWindow使用实例
- Android PopupWindow的使用技巧(转)
- Android的PopupWindow使用android学习之旅(四十三)
- Android PopupWindow的使用
- android PopupWindow 使用
- Android ListPopupWindow的使用
- Android的PopupWindow使用android学习之旅(四十三)
- Android PopupWindow的使用
- Android PopupWindow RadioGroup RadioButton 的使用
- android popupwindow的使用与讲解
- 【Android UI设计与开发】6.底部菜单栏(三)使用Fragment+PopupWindow仿QQ空间最新版底部菜单栏
- Android PopupWindow的使用
- Android的PopupWindow使用android学习之旅(四十三)
- android之PopUpWindow使用实例
- Android PopupWindow的使用技巧
- android PopupWindow的使用
- android PopupWindow使用实例
- Android PopupWindow的使用和分析
- Android PopupWindow的使用和分析
- Android PopupWindow的使用