Android PopUpWindow基本使用

花椒CX發表於2018-06-26

目的

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();
複製程式碼

不過這個方法嘗試了只能獲取佈局中內容的實際高度,而不能獲取佈局的實際高度,所以一般我不用。

相關文章