github地址(完整Demo,欢迎下载)
https://github.com/zhouxu88/CustomPopupWindow
在我这次的项目中,用到了很多的PopupWindow,如果一个个写,会累死人不说,而且只是做了大量的重复劳动而已,于是就尝试着动手封装了一下通用的PopupWindow,在此记录一下,顺便与有需要的朋友分享一下。
效果图,上2张
1、通常的使用
一般我们配置一个 PopupWindow通常的套路如下:
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View popUpView = inflater.inflate(R.layout.pop_select_num_spec, null, false);
selectNumSpecPop = new PopupWindow(popUpView, LinearLayoutCompat.LayoutParams.MATCH_PARENT, LinearLayoutCompat.LayoutParams.WRAP_CONTENT);
selectNumSpecPop.setOutsideTouchable(true);
popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
//设置PopupWindow的动画效果
selectNumSpecPop.setAnimationStyle(R.style.anim_popUpWindow_bottom);
然后我们还需要添加动画,监听back键等等,并且去findViewById来获取Pop内部的控件,然后,另外一个需要用到的时候,又得重复写,真心很累。
那么,封装之后的Pop如下:
//初始化PopupWindow
private void initPop() {
customPopupWindow = new CustomPopupWindow.Builder(this)
.setContentView(R.layout.pop_layout)
.setwidth(LinearLayout.LayoutParams.MATCH_PARENT)
.setheight(LinearLayout.LayoutParams.WRAP_CONTENT)
.setAnimationStyle(R.style.anim_popUpWindow_bottom)
.build();
//获取pop内部的控件
TextView cancelTv = (TextView)customPopupWindow.getItemView(R.id.cancel_tv);
//显示pop
customPopupWindow.showAtLocation(showPopBtn, Gravity.BOTTOM, 0, 0);
}
通过Builder的形式来构建Pop,这种链式写法,有没有很熟悉,很简洁。
这里,我是把pop那些需要设置的属性,都封装在了一个自定义的Builder类中,便于自己去定义
2、封装思路
cnotentview ,为了避免每次都来个 LayoutInflater.from(mContext).inflate,我们封装成一个 id
大小,就是给PopupWindow 设置宽高
显示位置,显示就两个函数 ,showAtLocation 和 showAsLocation 我们也只需要传入 view即可
基本就可以了,至于其他附加项,比如动画,点击外部取消,监听back键,或者简单 contentview 控件的点击事件,都是变动的。这里主要是用 Builder 的模式构建Pop常用的一些属性。
3、完整的Pop的代码
/**
* 封装的PopupWindow
*
* 作者: 周旭 on 2017/7/10/0010.
* 邮箱:374952705@qq.com
* 博客:http://www.jianshu.com/u/56db5d78044d
*/
public class CustomPopupWindow {
private PopupWindow mPopupWindow;
private View contentView;
private static Context mContext;
public CustomPopupWindow(Builder builder) {
contentView = LayoutInflater.from(mContext).inflate(builder.contentViewId, null);
mPopupWindow = new PopupWindow(contentView, builder.width, builder.height);
//设置点击外部可以取消,必须和下面这个方法配合才有效
mPopupWindow.setOutsideTouchable(true);
//设置一个空背景,设置了这个背景之后,设置点击外部取消才有效
mPopupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
//Popupwindow可以点击,PopupWindow弹出后,所有的触屏和物理按键都有PopupWindows处理。
// 其他任何事件的响应都必须发生在PopupWindow消失之后, (home 等系统层面的事件除外)。
// 比如这样一个PopupWindow出现的时候,按back键首先是让PopupWindow消失,
// 第二次按才是退出activity,
mPopupWindow.setFocusable(true);
mPopupWindow.setAnimationStyle(builder.animStyle); //设置pop显示的动画效果
}
/**
* popup 消失
*/
public void dismiss() {
if (mPopupWindow != null && mPopupWindow.isShowing()) {
mPopupWindow.dismiss();
}
}
/**
* 相对于窗体的显示位置
*
* @param view 可以为Activity中的任意一个View(最终的效果一样),
* 会通过这个View找到其父Window,也就是Activity的Window。
* @param gravity 在窗体中的位置,默认为Gravity.NO_GRAVITY
* @param x 表示距离Window边缘的距离,方向由Gravity决定。
* 例如:设置了Gravity.TOP,则y表示与Window上边缘的距离;
* 而如果设置了Gravity.BOTTOM,则y表示与下边缘的距离。
* @param y
* @return
*/
public CustomPopupWindow showAtLocation(View view, int gravity, int x, int y) {
if (mPopupWindow != null) {
mPopupWindow.showAtLocation(view, gravity, x, y);
}
return this;
}
/**
* 显示在anchor控件的正下方,或者相对这个控件的位置
*
* @param anchor
* @param xoff
* @param yoff
* @param gravity
* @return
*/
public CustomPopupWindow showAsDropDown(View anchor, int xoff, int yoff,int gravity) {
if (mPopupWindow != null) {
mPopupWindow.showAsDropDown(anchor, xoff, yoff,gravity);
}
return this;
}
/**
* 根据id获取view
*
* @param viewId
* @return
*/
public View getItemView(int viewId) {
if (mPopupWindow != null) {
return contentView.findViewById(viewId);
}
return null;
}
/**
* 根据id设置pop内部的控件的点击事件的监听
*
* @param viewId
* @param listener
*/
public void setOnClickListener(int viewId, View.OnClickListener listener) {
View view = getItemView(viewId);
view.setOnClickListener(listener);
}
/**
* builder 类
*/
public static class Builder {
private int contentViewId; //pop的布局文件
private int width; //pop的宽度
private int height; //pop的高度
private int animStyle; //动画效果
public Builder(Context context) {
mContext = context;
}
public Builder setContentView(int contentViewId) {
this.contentViewId = contentViewId;
return this;
}
public Builder setwidth(int width) {
this.width = width;
return this;
}
public Builder setheight(int height) {
this.height = height;
return this;
}
public Builder setAnimationStyle(int animStyle) {
this.animStyle = animStyle;
return this;
}
public CustomPopupWindow build() {
return new CustomPopupWindow(this);
}
}
}
最后,附上一篇关于PopUpWindow常用方法和一些参数的详解
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/0702/1627.html