目的
Popupwindow這個老傢伙,在API 1中就已經出現了,然而平時工作疏於總結,昨晚想用時,一時手生,竟然想不起來怎麼用,這裡特地記錄一下,如有不到之處,請指出,敬請諒解。
常用API解讀
這裡就用我最常用的API,其它的限於精力就不一一解釋了。
1、PopupWindow(View contentView, int width, int height, boolean focusable)
- 官方解讀:Create a new popup window which can display the contentView.
- 這個很簡單,構造方法,包含使用的佈局、大小、是否可以獲取焦點。
2、setAnimationStyle(int animationStyle)
- 設定出廠或者入場動畫,具體在下面的style檔案中會有說明。
3、setBackgroundDrawable(Drawable background)
- 這是一個奇葩的屬性,如果不設定PopupWindow的背景,無論是點選外部區域還是Back鍵都無法dismiss彈框.
- 例如:setBackgroundDrawable(new ColorDrawable(Color.parseColor("#00ffffff"))),這裡也可以換成drawable下的圖片
4、setOnDismissListener(PopupWindow.OnDismissListener onDismissListener)
- 顧名思義,介面消失事件監聽
5、setOutsideTouchable(boolean touchable)
6、showAsDropDown(View anchor)
7、showAtLocation(View parent, int gravity, int x, int y)
8、update(int x, int y, int width, int height, boolean force)
- 這個用的比較少,用於更新popupwindow已設定的一些屬性
樣式程式碼
//載入pop View parentView = LayoutInflater.from(PopUpWindowActivity.this).inflate(R.layout.popupwindow_content,null); RecyclerView recyclerView = parentView.findViewById(R.id.id_recycleView); recyclerView.setLayoutManager(new LinearLayoutManager(PopUpWindowActivity.this,LinearLayoutManager.VERTICAL,false)); List stringList = getListString(); MyRecyclerViewAdapter myRecyclerViewAdapter = new MyRecyclerViewAdapter(stringList); recyclerView.setAdapter(myRecyclerViewAdapter); popupWindow = new PopupWindow(parentView, getRootViewWidth(),getRootViewHeight() / 3,true);// popupWindow.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#00ffffff"))); popupWindow.setOutsideTouchable(true); popupWindow.showAtLocation(view,Gravity.BOTTOM,0,0); /** * 獲取螢幕寬度 * @return */ int getRootViewWidth(){ DisplayMetrics dm = getResources().getDisplayMetrics(); return dm.widthPixels; } /** * 獲取螢幕高度 * @return */ int getRootViewHeight(){ DisplayMetrics dm = getResources().getDisplayMetrics(); return dm.heightPixels; }
RecyclerView部分請自行Google。
常見疑問
1、為什麼點選空白區域無法dismiss?
因為你沒有設定背景顏色,哈哈,感覺這是Google的bug。
2、背景如何變暗?
WindowManager.LayoutParams layoutParams = MainActivity.this.getWindow().getAttributes(); layoutParams.alpha = 0.5f; //0.0-1.0 MainActivity.this.getWindow().setAttributes(layoutParams); getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
前面三行是通用的背景變暗方法。最後一行是為了解決部分手機不變暗和畫面閃現的原因。
3、我想新增入場和出場動畫
這裡用屬性動畫,通過引用style檔案中自定義的動畫實現,具體屬性動畫,還請種類和使用方法Google。
底部彈出和縮回動畫
in:
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate android:fromYDelta="10%p" android:toYDelta="0"
android:duration="@android:integer/config_mediumAnimTime"/>
<alpha android:fromAlpha="0.5" android:toAlpha="1.0"
android:duration="@android:integer/config_mediumAnimTime" />
</set>
複製程式碼
out:
<translate android:fromYDelta="0%p" android:toYDelta="100%p"
android:duration="@android:integer/config_mediumAnimTime"/>
<alpha android:fromAlpha="1.0" android:toAlpha="0.5"
android:duration="@android:integer/config_mediumAnimTime" />
複製程式碼
style:
<style name="pop_anim">
<item name="android:windowEnterAnimation">@anim/pop_in</item>
<item name="android:windowExitAnimation">@anim/pop_out</item>
</style>
複製程式碼
4、(更新)我想讓控制元件顯示在view的上方 (2018年6月27日19:12:29)
//獲取控制元件在螢幕上的位置,並賦值給location陣列
int[] location = new int[2];
view.getLocationOnScreen(location);
popupWindow.showAtLocation(view, Gravity.NO_GRAVITY, (location[0]), (location[1] - getRootViewHeight() / 3));
複製程式碼
- 其中,popupWindow本身的高度就是getRootViewHeight() / 3,不然底部無法和view的上部對齊。
還有個方法,用於獲取xml檔案中設定的高度
//獲取自身的長寬高
parentView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
int popupHeight = parentView.getMeasuredHeight();
int popupWidth = parentView.getMeasuredWidth();
複製程式碼
不過這個方法嘗試了只能獲取佈局中內容的實際高度,而不能獲取佈局的實際高度,所以一般我不用。