PopupWindow使用總結

一、構造函數

1、包含Context的構造函數

 public PopupWindow (Context context ) {
        this( context, null);
    }

PopupWindow的一些屬性會和應用設置的主題相關,自帶背景(如果不設置背景,可能不能全屏)

2、不包含Context的構造函數

public PopupWindow () {
        this( null, 0, 0);
    }

屬性和應用的主題無關,沒有背景(如果不設置背景,則PopupWindow外面點擊不能消失)

二、常見的設置

mPopupWindow.setContentView(view); //設置View
mPopupWindow.setWidth(getScreenWidth(this)/4);//設置寬高
mPopupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
mPopupWindow.setBackgroundDrawable(new BitmapDrawable());//設置背景(重要)
mPopupWindow.setOutsideTouchable(true);//PopupWindow外點擊
mPopupWindow.setFocusable(true);
mPopupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
    @Override
    public void onDismiss() {

    }
});

三、PopupWindow顯示的位置

PopupWindow控制顯示位置有兩種方法,一種是根據參照View,加上偏移座標,確定PopupWindow的位置;另外一種是根據屏幕的位置(gravity)加上偏移座標,確定PopupWindow的位置,不管是哪一種,PopupWindow是一種Window,都是通過WindowManager.LayoutParams來確定Window的位置。

1、根據參照的View,確定位置

mPopupWindow.showAsDropDown(view);//View左下角座標爲起始座標
mPopupWindow.showAsDropDown(view,getScreenWidth(this)/2,0);//View左下角座標加上偏移爲起始座標
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    mPopupWindow.showAsDropDown(view,0,0,Gravity.RIGHT);//api 19之後纔有調用,View的左邊或者右邊位置加偏移
}

這種方式內部的實現是通過參照View在屏幕中的座標,加上偏移,確定PopupWindow在屏幕中的位置,當顯示PopupWindow的空間不足時,可以把PopupWindow變成滾動的View

2、根據屏幕位置,確定PopupWindow的位置

mPopupWindow.showAtLocation(view,Gravity.BOTTOM|Gravity.LEFT,0,0);//屏幕的起始位置加上偏移

使用這種方法有時需要獲取一些控件的座標和寬高,但是在Activity的生命週期方法(onCreate,onResum)裏面,是獲取的數據可能有爲0,需要等到View渲染完成之後才能得到數據:

 public interface ViewDataObserver {
        void getViewData(int x, int y);
    }

    /**
     * View渲染完成之後,獲取View的座標,或者是View的寬高
     * @param view 獲取數據的View
     * @param isLocation true是獲取View座標,false獲取View的寬高
     * @param viewTreeObserver 獲取數據後的回調
     */
    public static void getViewData(final  View view, final boolean isLocation,final ViewDataObserver viewTreeObserver){
        view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                    @Override
                    public void onGlobalLayout() {
                        if (isLocation){
                            //獲取在整個屏幕內的絕對座標
                            int[] location = new  int[2] ;
                            view.getLocationOnScreen(location);
                            viewTreeObserver.getViewData(location[0], location[1]);
                        }else {
                            //獲取View的寬高
                            viewTreeObserver.getViewData(view.getWidth(), view.getHeight());
                        }
                        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN){
                            view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                        }else{
                            view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                        }
                    }
        });
    }

四、PopupWindow動畫設置

PopupWindow設置動畫:

mPopupWindow.setAnimationStyle(R.style.pop_anim_style);

準備彈出和消失的動畫

  <style name="pop_anim_style">
        <item name="android:windowEnterAnimation">@anim/popshow</item>
        <item name="android:windowExitAnimation">@anim/popdismiss</item>
    </style>

彈出的動畫:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:fromXDelta="0"
        android:toXDelta="0"
        android:fromYDelta="1200"
        android:toYDelta="0"
        android:duration="300" />
</set>

消失的動畫:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:fromXDelta="0"
        android:toXDelta="0"
        android:fromYDelta="0"
        android:toYDelta="1200"
        android:duration="300" />
</set>

五、PopupWindow更新

在創建好的PopupWindow,可以調用update方法來更新PopupWindow的大小和位置。

 mPopupWindow.update(0, 0, getScreenWidth(this) / 2, getScreenHeight(this) / 2);

六、背景變暗

在彈出PopupWindow的Activity佈局下面加上一個半透明的View,在彈出PopupWindow時顯示,消失時隱藏。

        <ImageView
            android:id="@+id/mExpertOverlay"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#66000000"
            android:visibility="gone"/>

七、ListPopupWindow

包含一個列表的PopupWindow,直接設置Adapter就OK

mListPopupWindow=new ListPopupWindow(this);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.item);
adapter.add("北京");
adapter.add("上海");
adapter.add("廣州");
adapter.add("深圳");
adapter.add("重慶");
mListPopupWindow.setAdapter(adapter);
mListPopupWindow.setWidth(getScreenWidth(this));
mListPopupWindow.setHeight(getScreenHeight(this) / 3);
mListPopupWindow.setModal(true);
mListPopupWindow.setAnchorView(view);
mListPopupWindow.setBackgroundDrawable(new BitmapDrawable());
mListPopupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
    @Override
    public void onDismiss() {

    }
});
mListPopupWindow.show();
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章