一、構造函數
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();