关于popupwindows一点总结
2018-09-18 本文已影响0人
学无止境的cy
开发中遇到这样的一个需求,就是要把日历展示出来上面不透明,下面做透明处理
需求
图好像有点大。。。说下自己第一次做这个需求的心历路程。
planA:在创建popupwindow的时候我们把他的宽和高都设置成match_parent,然后放在我们需要放的位置下方就完了。
可实际效果并不是和我们想象的一样,给个实际的效果图
根据view的绘制原理我们知道当我们设置match_parent的时候我们当前的子view绘制的大小是根据父view决定的,父view多大,我们的子view就有多大,而我们pop的父view就是整个的activity.(思考:我们能否将pop的父view变为我们自己需要放入的容器内)
附一篇view的绘制原理讲的很不错的文章https://www.jianshu.com/p/5a71014e7b1b
planB:使用fragmelayout覆盖我们的当前布局,貌似应该可以.
但是我们的这个pop的父view并不是在一个完整的activity当中,而是在一个fragment当中。实际效果图我用同事写的另一个相识功能代替
planB
可以看到我们fragment的下面的切换栏并没有被半透明化
PlanC:根据planA演变而来 我们只用算出我们剩余的高度然后设置进去就ok了
问题1;fragmen中获取view的位置的时机:
在fragment当中的oncreateview方法当中直接获取某个view的位置信息一般是获取不到的,如果你要获取某个view的位置信息通过
view.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
//这个remover不要漏掉否则这个监听可能会反复调用
view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
然后就是在pop里面计算我们剩余的高度了
//计算当前view所在坐标(全局)
int[] location = new int[2];
view.getLocationOnScreen(location);
int viewY = location[1];
//获取控件的高度
int viewHeight = view.getHeight();
//获取屏幕的高度
WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics dm = new DisplayMetrics();
//得到我们控件所需高度
int popHeight = dm.heightPixels - viewHeight - viewY;
this.setHeight(popHeight);
具体怎么计算的很简单注释也很清楚,需要注意的是我们通过view.getY()得到的Y的坐标和我们locationOnscreen中的坐标是不同,具体指的什么大家可以自己去看下。至此我们的这个需求就解决了,很多人都说面试的时候问什么view的绘制原理 源码等一些的有点造火箭的感觉,其实不然。要是你对view的绘制原理很熟悉的时候,在planA出现的状况的时候你就能立刻想到是什么问题了,并能拿出正确的解决办法。