效果图:
Tips:这里的适用场景是,程序中多次使用同样的Popwindow,如果你使用的popwindow,只是个别地方使用,建议看这篇文章:
普通Popwindow的封装(包含动画)
封装的pop使用起来非常简单:
add_line2.setOnClickListener({
mCustomPopWindow = CustomPopWindow.PopupWindowBuilder(this)
.setView(this)
.setAnimationStyle(R.style.popwin_anim_style)//设置显示和隐藏动画
.enableBackgroundDark(true) //弹出popWindow时,背景是否变暗
.setBgDarkAlpha(0.7f) // 控制亮度
.setOnDissmissListener { Log.e("TAG", "pop消失监听") }
.create()
.showAsDropDown(add_line2, 0, 0, Gravity.BOTTOM)//设定位置,Gravity里有多个位置可以设置
.setClickHomeListener { toast("点击首页") }
.setClickTongjiListener { toast("统计资料") }
})
几行代码,就创建了popwindow,而且有回调方法,即使传值,跳转到其他界面,也可以随心所欲,over!
封装的Popwindow源码为:
package com.paint.user.adaptertest;
import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.support.annotation.RequiresApi;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.PopupWindow;
public class CustomPopWindow implements PopupWindow.OnDismissListener {
private static final String TAG = "CustomPopWindow";
private static final float DEFAULT_ALPHA = 0.7F;
private Context mContext;
private int mWidth;
private int mHeight;
private boolean mIsFocusable;
private boolean mIsOutside;
private int mResLayoutId;
private View mContentView;
private PopupWindow mPopupWindow;
private int mAnimationStyle;
private boolean mClippEnable;
private boolean mIgnoreCheekPress;
private int mInputMode;
private PopupWindow.OnDismissListener mOnDismissListener;
private int mSoftInputMode;
private boolean mTouchable;
private View.OnTouchListener mOnTouchListener;
private Window mWindow;
private boolean mIsBackgroundDark;
private float mBackgroundDrakValue;
private boolean enableOutsideTouchDisMiss;
private static OnItemClickHomeListener mOnClickHomeListener;
private static OnItemClickTongjiListener mOnClickTongjiListener;
//自定义点击事件,回调
public interface OnItemClickHomeListener {
void onClickHome();
}
public interface OnItemClickTongjiListener {
void onClickTongji();
}
public CustomPopWindow setClickHomeListener(OnItemClickHomeListener mOnItemClickListener) {
this.mOnClickHomeListener = mOnItemClickListener;
return this;
}
public CustomPopWindow setClickTongjiListener(OnItemClickTongjiListener mOnItemClickListener) {
this.mOnClickTongjiListener = mOnItemClickListener;
return this;
}
private CustomPopWindow(Context context) {
this.mIsFocusable = true;
this.mIsOutside = true;
this.mResLayoutId = -1;
this.mAnimationStyle = -1;
this.mClippEnable = true;
this.mIgnoreCheekPress = false;
this.mInputMode = -1;
this.mSoftInputMode = -1;
this.mTouchable = true;
this.mIsBackgroundDark = false;
this.mBackgroundDrakValue = 0.0F;
this.enableOutsideTouchDisMiss = true;
this.mContext = context;
}
public int getWidth() {
return this.mWidth;
}
public int getHeight() {
return this.mHeight;
}
public CustomPopWindow showAsDropDown(View anchor, int xOff, int yOff) {
if (this.mPopupWindow != null) {
this.mPopupWindow.showAsDropDown(anchor, xOff, yOff);
}
return this;
}
public CustomPopWindow showAsDropDown(View anchor) {
if (this.mPopupWindow != null) {
this.mPopupWindow.showAsDropDown(anchor);
}
return this;
}
@RequiresApi(
api = 19
)
public CustomPopWindow showAsDropDown(View anchor, int xOff, int yOff, int gravity) {
if (this.mPopupWindow != null) {
this.mPopupWindow.showAsDropDown(anchor, xOff, yOff, gravity);
}
return this;
}
public CustomPopWindow showAtLocation(View parent, int gravity, int x, int y) {
if (this.mPopupWindow != null) {
this.mPopupWindow.showAtLocation(parent, gravity, x, y);
}
return this;
}
private void apply(PopupWindow popupWindow) {
popupWindow.setClippingEnabled(this.mClippEnable);
if (this.mIgnoreCheekPress) {
popupWindow.setIgnoreCheekPress();
}
if (this.mInputMode != -1) {
popupWindow.setInputMethodMode(this.mInputMode);
}
if (this.mSoftInputMode != -1) {
popupWindow.setSoftInputMode(this.mSoftInputMode);
}
if (this.mOnDismissListener != null) {
popupWindow.setOnDismissListener(this.mOnDismissListener);
}
if (this.mOnTouchListener != null) {
popupWindow.setTouchInterceptor(this.mOnTouchListener);
}
popupWindow.setTouchable(this.mTouchable);
}
private PopupWindow build() {
if (this.mContentView == null) {
//this.mResLayoutId = R.layout.pop_menu;//固定
this.mContentView = LayoutInflater.from(this.mContext).inflate(this.mResLayoutId, (ViewGroup) null);
}
Activity activity = (Activity) this.mContentView.getContext();
if (activity != null && this.mIsBackgroundDark) {
float alpha = this.mBackgroundDrakValue > 0.0F && this.mBackgroundDrakValue < 1.0F ? this.mBackgroundDrakValue : 0.7F;
this.mWindow = activity.getWindow();
WindowManager.LayoutParams params = this.mWindow.getAttributes();
params.alpha = alpha;
this.mWindow.addFlags(2);
this.mWindow.setAttributes(params);
}
if (this.mWidth != 0 && this.mHeight != 0) {
this.mPopupWindow = new PopupWindow(this.mContentView, this.mWidth, this.mHeight);
} else {
this.mPopupWindow = new PopupWindow(this.mContentView, -2, -2);
}
if (this.mAnimationStyle != -1) {
this.mPopupWindow.setAnimationStyle(this.mAnimationStyle);
}
this.apply(this.mPopupWindow);
if (this.mWidth == 0 || this.mHeight == 0) {
this.mPopupWindow.getContentView().measure(0, 0);
this.mWidth = this.mPopupWindow.getContentView().getMeasuredWidth();
this.mHeight = this.mPopupWindow.getContentView().getMeasuredHeight();
}
this.mPopupWindow.setOnDismissListener(this);
if (!this.enableOutsideTouchDisMiss) {
this.mPopupWindow.setFocusable(true);
this.mPopupWindow.setOutsideTouchable(false);
this.mPopupWindow.setBackgroundDrawable((Drawable) null);
this.mPopupWindow.getContentView().setFocusable(true);
this.mPopupWindow.getContentView().setFocusableInTouchMode(true);
this.mPopupWindow.getContentView().setOnKeyListener(new View.OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == 4) {
CustomPopWindow.this.mPopupWindow.dismiss();
return true;
} else {
return false;
}
}
});
this.mPopupWindow.setTouchInterceptor(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
if (event.getAction() != 0 || x >= 0 && x < CustomPopWindow.this.mWidth && y >= 0 && y < CustomPopWindow.this.mHeight) {
if (event.getAction() == 4) {
Log.e("CustomPopWindow", "out side ...");
return true;
} else {
return false;
}
} else {
Log.e("CustomPopWindow", "out side ");
Log.e("CustomPopWindow", "width:" + CustomPopWindow.this.mPopupWindow.getWidth() + "height:" + CustomPopWindow.this.mPopupWindow.getHeight() + " x:" + x + " y :" + y);
return true;
}
}
});
} else {
this.mPopupWindow.setFocusable(this.mIsFocusable);
this.mPopupWindow.setBackgroundDrawable(new ColorDrawable(0));
this.mPopupWindow.setOutsideTouchable(this.mIsOutside);
}
this.mPopupWindow.update();
return this.mPopupWindow;
}
public void onDismiss() {
this.dissmiss();
}
public void dissmiss() {
if (this.mOnDismissListener != null) {
this.mOnDismissListener.onDismiss();
}
if (this.mWindow != null) {
WindowManager.LayoutParams params = this.mWindow.getAttributes();
params.alpha = 1.0F;
this.mWindow.setAttributes(params);
}
if (this.mPopupWindow != null && this.mPopupWindow.isShowing()) {
this.mPopupWindow.dismiss();
}
}
public PopupWindow getPopupWindow() {
return this.mPopupWindow;
}
public static class PopupWindowBuilder {
private CustomPopWindow mCustomPopWindow;
public PopupWindowBuilder(Context context) {
this.mCustomPopWindow = new CustomPopWindow(context);
}
public PopupWindowBuilder size(int width, int height) {
this.mCustomPopWindow.mWidth = width;
this.mCustomPopWindow.mHeight = height;
return this;
}
public PopupWindowBuilder setFocusable(boolean focusable) {
this.mCustomPopWindow.mIsFocusable = focusable;
return this;
}
public PopupWindowBuilder setView() {
this.mCustomPopWindow.mResLayoutId = R.layout.pop_more_race;//直接写死,多处用
this.mCustomPopWindow.mContentView = null;
return this;
}
public PopupWindowBuilder setView(Context context) {
View contentView = LayoutInflater.from(context).inflate(R.layout.pop_more_race, null);
this.mCustomPopWindow.mContentView = contentView;
handleLogic(context, contentView);
this.mCustomPopWindow.mResLayoutId = -1;
return this;
}
public PopupWindowBuilder setOutsideTouchable(boolean outsideTouchable) {
this.mCustomPopWindow.mIsOutside = outsideTouchable;
return this;
}
public PopupWindowBuilder setAnimationStyle(int animationStyle) {
this.mCustomPopWindow.mAnimationStyle = animationStyle;
return this;
}
public PopupWindowBuilder setClippingEnable(boolean enable) {
this.mCustomPopWindow.mClippEnable = enable;
return this;
}
public PopupWindowBuilder setIgnoreCheekPress(boolean ignoreCheekPress) {
this.mCustomPopWindow.mIgnoreCheekPress = ignoreCheekPress;
return this;
}
public PopupWindowBuilder setInputMethodMode(int mode) {
this.mCustomPopWindow.mInputMode = mode;
return this;
}
public PopupWindowBuilder setOnDissmissListener(PopupWindow.OnDismissListener onDissmissListener) {
this.mCustomPopWindow.mOnDismissListener = onDissmissListener;
return this;
}
public PopupWindowBuilder setSoftInputMode(int softInputMode) {
this.mCustomPopWindow.mSoftInputMode = softInputMode;
return this;
}
public PopupWindowBuilder setTouchable(boolean touchable) {
this.mCustomPopWindow.mTouchable = touchable;
return this;
}
public PopupWindowBuilder setTouchIntercepter(View.OnTouchListener touchIntercepter) {
this.mCustomPopWindow.mOnTouchListener = touchIntercepter;
return this;
}
public PopupWindowBuilder enableBackgroundDark(boolean isDark) {
this.mCustomPopWindow.mIsBackgroundDark = isDark;
return this;
}
public PopupWindowBuilder setBgDarkAlpha(float darkValue) {
this.mCustomPopWindow.mBackgroundDrakValue = darkValue;
return this;
}
public PopupWindowBuilder enableOutsideTouchableDissmiss(boolean disMiss) {
this.mCustomPopWindow.enableOutsideTouchDisMiss = disMiss;
return this;
}
public CustomPopWindow create() {
this.mCustomPopWindow.build();
return this.mCustomPopWindow;
}
/**
* 处理弹出显示内容、点击事件等逻辑
*
* @param contentView
*/
private void handleLogic(final Context context, View contentView) {
View.OnClickListener listener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mCustomPopWindow != null) {
mCustomPopWindow.dissmiss();
}
switch (v.getId()) {
case R.id.race_back:
mOnClickHomeListener.onClickHome();
break;
case R.id.race_tongji:
mOnClickTongjiListener.onClickTongji();
break;
}
}
};
contentView.findViewById(R.id.race_back).setOnClickListener(listener);
contentView.findViewById(R.id.race_tongji).setOnClickListener(listener);
}
}
}
这实际上,就是将普通的Popwindow的布局,以及响应事件封装到了View里面:
读者可根据自己的业务需求,写不同的布局和回调事件即可:
至于上面用到的动画,可看这篇文章:
普通Popwindow的封装(包含动画)