PopupWindow的显示有两种:
- 一种是基于锚点的相对显示;
/**
* 下拉方式显示
* @param anchor the view on which to pin the popup window(锚点控件,popupWindow的参照系)
* @param xoff A horizontal offset from the anchor in pixels(相对锚点的水平偏移量)
* @param yoff A vertical offset from the anchor in pixels(相对锚点的的垂直偏移量)
* @param gravity Alignment of the popup relative to the anchor(锚点控件与popupwindow对齐的方式)
*/
public void showAsDropDown(View anchor, int xoff, int yoff, int gravity)
上效果图显示代码如下:
int margin = tvAnchor.getHeight();//外边距,为了让演示效果添加这个值
mPopupWindow.showAsDropDown(tvAnchor, margin, margin, Gravity.RIGHT);
这里的gravity这是用于指定popupWindow与anchor锚点View的左边届对齐还是右边界对齐(Gravity.LEFT/Gravity.RIGHT)
在通过锚点View以及对齐方式确定了popupWindow位置后,再通过yoff/xoff对位于anchor锚点View的下方的确定位置的popupWindow进行水平以及垂直方向的平移;
- 另外一种则是基于整个window的DecorView内部指定对齐方向和以对齐边界为起点的偏移量确定我们popupWindow位置的显示。
/**
* @param parent – a parent view to get the View.getWindowToken() token from(用于获取提供WindowToken<在wms与Application间通信使用>)
* @param gravity – the gravity which controls the placement of the popup window(popupWindow的对齐方式)
* @param x – the popup's x location offset(popupWindow在X轴的偏移量)
* @param y – the popup's y location offset(popupWindow在y轴的偏移量)
*/
public void showAtLocation(View parent, int gravity, int x, int y)
如上图效果:
X = tvAnchor.Left + margin
Y = statusBarHeight + actionBarHeight + tvAnchor.Bottom + margin
gravity = Gravity.LEFT | Gravity.TOP
上效果图显示代码如下:
int margin = tvAnchor.getHeight();//外边距,为了让演示效果添加这个值
mPopupWindow.showAtLocation(tvAnchor, Gravity.LEFT | Gravity.BOTTOM, tvAnchor.getLeft() + margin, tvAnchor.getBottom() + supportActionBar.getHeight() + statusBarHeight + margin);
过渡动画:
- 进场动画
public void setEnterTransition(@Nullable Transition enterTransition)
- 退场动画
public void setExitTransition(@Nullable Transition exitTransition)
- 动画样式,可以配置显示以及隐藏的动画等
/**
*如果当在显示的时候设置动画效果,则将会在下次展示的时候才会生效或者调用一次update()方法后才会生效;
*@param animationStyle : Set to -1 for the default animation, 0 for no animation, or a resource identifier for an explicit animation.(-1:默认动画;0:无动画;具体动画资源ID)
*/
public void setAnimationStyle(int animationStyle)
Slide过渡动画效果演示
demo部分主要代码:
View tvItem1 = popupView.findViewById(R.id.tv_item1);
tvItem1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(), "点击popupWindow里面的item", Toast.LENGTH_SHORT).show();
mPopupWindow.dismiss();
}
});
mPopupWindow = new PopupWindow(popupView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, true);
mPopupWindow.setWidth(tvAnchor.getWidth() / 2);//设置宽度
mPopupWindow.setOutsideTouchable(true);//是否接收窗口外部触摸事件
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Slide slide = new Slide();
slide.setDuration(300);
slide.setSlideEdge(Gravity.TOP);
mPopupWindow.setEnterTransition(slide);
mPopupWindow.setExitTransition(slide);
}
}
//mPopupWindow.setAnimationStyle(R.style.MyPopupWindow);
//getActionBar().getHeight()
int height = -1;
int statusBarHeight = -1;
int margin = tvAnchor.getHeight();
ActionBar supportActionBar = getSupportActionBar();
int resId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resId > 0) {
statusBarHeight = getResources().getDimensionPixelOffset(resId);
}
if (supportActionBar != null) {
height = supportActionBar.getHeight();
}
Log.e("test", " tvAnchor.getTop() = " + tvAnchor.getTop() + " tvAnchor.getHeight() = " + tvAnchor.getHeight() + " getSupportActionBar().getHeight() = " + height
+ " statusBarHeight = " + statusBarHeight);
//mPopupWindow.showAtLocation(tvAnchor, Gravity.LEFT | Gravity.BOTTOM, tvAnchor.getLeft() + margin, tvAnchor.getBottom() + supportActionBar.getHeight() + statusBarHeight + margin);
mPopupWindow.showAsDropDown(tvAnchor, margin, margin, Gravity.RIGHT);
Android官方文档 : https://developer.android.com/reference/android/widget/PopupWindow
想了解更多关于过渡动画见知识:https://developer.android.com/reference/android/transition/Transition