我们常见的PopupWindow使用如下:
PopupWindow popupWindow = new PopupWindow(contentView,width,height);
popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
popupWindow.setOutsideTouchable(true);
popupWindow.setAnimationStyle(R.style.PopupAnimation);
popupWindow.setTouchable(true);
popupWindow.setFocusable(true);
popupWindow.showAtLocation(anchor,gravity,x,y);
下面我们对每个方法逐个解释:
首先是构造函数,popupwindow有多个构造函数,这是其中一个,并且要生成一个popupwindow,这三个参数是必须的(即时你用其他构造函数):
View contentView:第一个参数是你PopupWindow的布局View,可以用inflate生成,PopupWindow没有默认布局。
width、height:这个是PopupWindow的显示出来的宽和高,这里的宽高会完全覆盖你PopupWindow布局xml文件中最顶层View的宽高。
setBackgroundDrawable():设置PopupWindow的背景。
setOutSideTouchable():设置PopupWindow之外的区域是否能响应点击事件。
setAnimationStyle():设置滑入滑出的动画效果。
setTouchable():设置PopupWindow是否能响应点击事件。
setFocusable():设置PopupWindow能否获取焦点。如果PopupWindow中有EditView时,需要获取焦点才能输入。
接下来看显示方法:
showAsDropDown(View anchor):相对某个空间的位置(正左下方),无偏移
showAsDropDown(View anchor,int xoff,int yoff):相对于某个空间的位置,可设置偏移量。
showAtLocation(View parent ,int gravity, int x, int y):相对于父控件的位置,例如正中央Gravity.CENTER、下方Gravity.BOTTOM等,可设置偏移量。
接下来将常见的用法:
1、如果想要点击PopupWindow之外的区域时,让PopupWindow消失
在showAtLocation()之前要加上这两句:
popupWindow.setOutsideTouchable(true);
popupWindow.setBackgroundDrawable(new BitmapDrawable());
只有同时设置PopupWindow的背景和setOutsideTouchable为true,才能响应外部点击事件,即点击外部或者按下“Back”键时,PopuptWindow才会消失。但是前提是你点击的是外部区域,如果你构造PopupWindow时是这样的:
popupWindow = new PopupWindow(LayoutInflater.from(MainActivity.this).inflate(R.layout.pop_list, null), ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
传入的width和height是MATCH_PARENT,也就是占据整个屏幕,那你就无法点击到外部区域,PopupWindow也就无法消失,所以应该使用固定的大小或者WRAP_CONTENT。
2、想要让PopupWindow从屏幕下方弹出
我们先看看showAtLocation参数的定义:
/**
* @param parent a parent view to get the {@link android.view.View#getWindowToken()} token from
* @param gravity the gravity which controls the placement of the popup window
* @param x the popup's x location offset
* @param y the popup's y location offset
*/
public void showAtLocation(View parent, int gravity, int x, int y)
第一个参数是一个View,这里解释该View是为了调用getWindowToken()来获取token的,
gravity:控制弹出窗口的位置
x和y:表示偏移量
view.getWindowToken()是获取该view所依附的window的唯一令牌。
public void showAtLocation(View parent, int gravity, int x, int y) {
mParentRootView = new WeakReference<>(parent.getRootView());
showAtLocation(parent.getWindowToken(), gravity, x, y);
}
可以看到这里传入的view只调用了getRootView获取根布局和getWindowToken方法获取window的token。
所以我们传入activity中任何一个view都没有影响。
想要让PopupWindow从底部弹出,只需要传入gravity为Gravity.Bottom即可:
showAtLocation(view, Gravity.BOTTOM,0,0);
3、滑入滑出动画效果
先在res下的anim文件夹中新建两个文件:
out.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromYDelta="0%p"
android:toYDelta="100%p"
android:duration="500"/>
</set>
enter.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromYDelta="100%p"
android:toYDelta="0"
android:duration="500"/>
</set>
然后再styles.xml的resources标签中加入style:
<resources>
<style name="PopupAnimation">
<item name="android:windowEnterAnimation">@anim/pop_enter</item>
<item name="android:windowExitAnimation">@anim/pop_out</item>
</style>
</resources>
使用时:
popupWindow.setAnimationStyle(R.style.PopupAnimation);
4、让空白区域为灰色半透明
在Popupwindow要展示的视图文件的根布局加个背景颜色为半透明