android 彈出Popupwindow 自適用(Activity或者Dialog)判斷向上還向下

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

1、Activity中彈出點(diǎn)擊按鈕彈出popupwindow
1.0:比如:


QQ圖片20170316110343.png

這種是要在Activity中的ListView中或者其他布局中展示要彈出的Popupwindow 直接向下即可沒什么好闡述的,很簡單的代碼

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

1.1:比如在底部點(diǎn)擊彈出Popupwindow


QQ圖片20170316110356.png

首先要顯示彈出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的高度


QQ圖片20170316111738.png

有人會(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ù)


QQ圖片20170316133454.jpg

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

m_Linearlayout.getLocationOnScreen(location);

下面來進(jìn)行剖析一下

QQ圖片20170316110400.png
QQ圖片20170316110405.png

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

QQ圖片20170316135514.png

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);

接下來看看效果!

QQ圖片20170316142326.jpg

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


QQ圖片20170316142958.jpg

也是可以正常上去的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容