今天來記錄一下在Activity中或者在(Dialog or Popupwindow )中點(diǎn)擊按鈕彈出popupwindow 自使用判斷是向下彈出還是向上彈出。
1、Activity中彈出點(diǎn)擊按鈕彈出popupwindow
1.0:比如:

這種是要在Activity中的ListView中或者其他布局中展示要彈出的Popupwindow 直接向下即可沒什么好闡述的,很簡單的代碼
m_popupwindow.showAsDropDown(放入View, 0, 0);
1.1:比如在底部點(diǎn)擊彈出Popupwindow

首先要顯示彈出Popupwindow 顯示個(gè)數(shù),如果超出則按照固定大小來進(jìn)行計(jì)算,否則自使用,這種也比較簡單
m_popupwindow.showAtLocation(放入View, Gravity.TOP | Gravity.START,
location[0],
location[1] - measuredHeight);
有人會(huì)問了 如何計(jì)算popupwindow是向下還是向上的呢?
1.1.0
首先需要計(jì)算一下彈出這個(gè)popupwindow的高度

有人會(huì)問了如果我里面的高度是不固定的呢?放的是ListView呢?別著急,后面會(huì)講到
高度的計(jì)算就是popupwindow內(nèi)View的高度
(popupwindow的View).getMeasuredHeight();
如果popupwindow用的是一個(gè)實(shí)例的話,那么剛開始new popupwindow的時(shí)候拿getMeasuredHeight()這個(gè)方法一直都是0,只有第二次才不為0,其中的為什么在此處就不分析了,只需要加入
(popupwindow的View).measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
1.1.1 即可,但是此處還有一個(gè)問題,第一次得到的是模板的高度,如果popupwindow內(nèi)放入的是ListView的話,那么將得到的是一個(gè)模板的高度,也就是是僅此一條數(shù)據(jù)的高度這里面,那么如何得到ListView內(nèi)數(shù)據(jù)的真實(shí)高度呢?所以這時(shí)候要限制里面的高度所以在new popupwindow的時(shí)候可以這么寫
if(數(shù)據(jù).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);
以上算法就僅當(dāng)PopupWindow是ListView不固定數(shù)據(jù) 如果是固定數(shù)據(jù)的話,那么直接
measuredHeight = m_view.getMeasuredHeight();
即可。但是如果將這個(gè)做成通用庫的話,怎么自動(dòng)進(jìn)行判斷是向上彈出,還是向下彈出呢?代碼如下:
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這個(gè)窗口的,如果是在Activity中彈出PopupWindow 而PopupWindow中的數(shù)據(jù)點(diǎn)擊繼續(xù)彈出PopupWindow呢,像這種數(shù)據(jù)

彈出來的PopupWindow 是不是在底部了,理論上來說應(yīng)該是底部高度不足的話,應(yīng)該從上方進(jìn)行彈出。如果我們還是規(guī)規(guī)矩矩的按照上面的那個(gè)寫法來進(jìn)行寫的話肯定會(huì)發(fā)現(xiàn)有問題
m_Linearlayout.getLocationOnScreen(location);
下面來進(jìn)行剖析一下


getLocationOnScreen 和 getLocationInWindow()方法區(qū)別

getLocationInWindow是以B為原點(diǎn)的C的坐標(biāo)
getLocationOnScreen以A為原點(diǎn)。
有些朋友可能明白了,是的~在彈窗中調(diào)用PopupWindow是使用getLocationInWindow。如果想將2.0中的那個(gè)PopupWindow彈出放到控件上方的話其實(shí)就很簡單了
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);
忙碌了一下,發(fā)現(xiàn)想把這個(gè)寫成通用控件,如何來進(jìn)行和在Activity中判斷一致自定來判斷底部距離來展示popupwindow是向上還是向下呢?代碼其實(shí)也很簡單!分析一下,將彈出框的總寬度計(jì)算出來,然后用屏幕高度來減去當(dāng)前窗口,得到的是空閑高度用之前的Activity判斷的方法減去這個(gè)空閑高度是不是就可以了呢?
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);
接下來看看效果!

居然真的跑上去了
再來看看在Activity中的時(shí)候

也是可以正常上去的。