关于popupwindows一点总结

2018-09-18  本文已影响0人  学无止境的cy

开发中遇到这样的一个需求,就是要把日历展示出来上面不透明,下面做透明处理


需求

图好像有点大。。。说下自己第一次做这个需求的心历路程。

planA:在创建popupwindow的时候我们把他的宽和高都设置成match_parent,然后放在我们需要放的位置下方就完了。

可实际效果并不是和我们想象的一样,给个实际的效果图

planA
根据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出现的状况的时候你就能立刻想到是什么问题了,并能拿出正确的解决办法。

上一篇下一篇

猜你喜欢

热点阅读