android 弹出Popupwindow 自适用(Activity或者Dialog)判断向上还向下

今天来记录一下在Activity中或者在(Dialog or Popupwindow )中点击按钮弹出popupwindow 自使用判断是向下弹出还是向上弹出。

1、Activity中弹出点击按钮弹出popupwindow
1.0:比如:


QQ图片20170316110343.png

这种是要在Activity中的ListView中或者其他布局中展示要弹出的Popupwindow 直接向下即可没什么好阐述的,很简单的代码

m_popupwindow.showAsDropDown(放入View, 0, 0);

1.1:比如在底部点击弹出Popupwindow


QQ图片20170316110356.png

首先要显示弹出Popupwindow 显示个数,如果超出则按照固定大小来进行计算,否则自使用,这种也比较简单

m_popupwindow.showAtLocation(放入View, Gravity.TOP | Gravity.START,
                                                                      location[0],
                                                                      location[1] - measuredHeight);

有人会问了 如何计算popupwindow是向下还是向上的呢?
1.1.0
首先需要计算一下弹出这个popupwindow的高度


QQ图片20170316111738.png

有人会问了如果我里面的高度是不固定的呢?放的是ListView呢?别着急,后面会讲到
高度的计算就是popupwindow内View的高度

(popupwindow的View).getMeasuredHeight();

如果popupwindow用的是一个实例的话,那么刚开始new popupwindow的时候拿getMeasuredHeight()这个方法一直都是0,只有第二次才不为0,其中的为什么在此处就不分析了,只需要加入

(popupwindow的View).measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);

1.1.1 即可,但是此处还有一个问题,第一次得到的是模板的高度,如果popupwindow内放入的是ListView的话,那么将得到的是一个模板的高度,也就是是仅此一条数据的高度这里面,那么如何得到ListView内数据的真实高度呢?所以这时候要限制里面的高度所以在new popupwindow的时候可以这么写

if(数据.size() > 4){
     m_popupwindow = new PopupWindow(m_view,LayoutParams.WRAP_CONTENT, DensityUtil.dip2px(m_context, 200));// LayoutParams.WRAP_CONTENT);
}else{
    m_popupwindow = new PopupWindow(m_view, LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
}

所以接下来要获取上述的问题就可以这么做

measuredHeight = m_view.getMeasuredHeight();
measuredHeight = (m_data.length > 4 ? DensityUtil.dip2px(m_context, 200) : (measuredHeight - 1) * m_data.length);

以上算法就仅当PopupWindow是ListView不固定数据 如果是固定数据的话,那么直接

measuredHeight = m_view.getMeasuredHeight();

即可。但是如果将这个做成通用库的话,怎么自动进行判断是向上弹出,还是向下弹出呢?代码如下:

 boolean isNeedShowUp = (screenHeight - location[1] - m_Linearlayout.getHeight() < measuredHeight);
 if (!isNeedShowUp) {
       m_popupwindow.showAsDropDown(ComboBox.this, 0, 0);
  } else {
       m_popupwindow.showAtLocation(m_Button, Gravity.TOP | Gravity.START,location[0],location[1] - measuredHeight);
 }

2.0 以上是基于Activity这个窗口的,如果是在Activity中弹出PopupWindow 而PopupWindow中的数据点击继续弹出PopupWindow呢,像这种数据


QQ图片20170316133454.jpg

弹出来的PopupWindow 是不是在底部了,理论上来说应该是底部高度不足的话,应该从上方进行弹出。如果我们还是规规矩矩的按照上面的那个写法来进行写的话肯定会发现有问题

m_Linearlayout.getLocationOnScreen(location);

下面来进行剖析一下

QQ图片20170316110400.png
QQ图片20170316110405.png

getLocationOnScreen 和 getLocationInWindow()方法区别

QQ图片20170316135514.png

getLocationInWindow是以B为原点的C的坐标
getLocationOnScreen以A为原点。
有些朋友可能明白了,是的~在弹窗中调用PopupWindow是使用getLocationInWindow。如果想将2.0中的那个PopupWindow弹出放到控件上方的话其实就很简单了

m_Linearlayout.getLocationInWindow(location);
m_popupwindow.showAtLocation(m_Button, Gravity.TOP | Gravity.START,location[0],location[1] - measuredHeight);

放在控件的下方的很很简单和之前的一样

m_popupwindow.showAsDropDown(m_Button, 0, 0);

忙碌了一下,发现想把这个写成通用控件,如何来进行和在Activity中判断一致自定来判断底部距离来展示popupwindow是向上还是向下呢?代码其实也很简单!分析一下,将弹出框的总宽度计算出来,然后用屏幕高度来减去当前窗口,得到的是空闲高度用之前的Activity判断的方法减去这个空闲高度是不是就可以了呢?

location_dialog = new int[2];
dialogView.getLocationOnScreen(location_dialog);
location_dialog[1] += dialogView.getMeasuredHeight();
boolean isNeedShowUp = (location_dialog[1] - (screenHeight - location_dialog[1]) - location[1] - m_Linearlayout.getHeight() < measuredHeight);

接下来看看效果!

QQ图片20170316142326.jpg

居然真的跑上去了
再来看看在Activity中的时候


QQ图片20170316142958.jpg

也是可以正常上去的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容