package com.future.dispatch.utils.EasePopup; import android.app.Activity; import android.content.Context; import android.graphics.Color; import android.graphics.Rect; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.Build; import android.transition.Transition; import android.util.Log; import android.view.Gravity; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.ViewGroupOverlay; import android.view.ViewTreeObserver; import android.view.WindowManager; import android.widget.PopupWindow; import androidx.annotation.ColorInt; import androidx.annotation.FloatRange; import androidx.annotation.IdRes; import androidx.annotation.LayoutRes; import androidx.annotation.NonNull; import androidx.annotation.RequiresApi; import androidx.annotation.StyleRes; import androidx.core.widget.PopupWindowCompat; import com.future.dispatch.utils.BottomBarUtils; /** * Created by zyyoona7 on 2017/8/3. *

* PopupWindow封装 */ public abstract class BasePopup implements PopupWindow.OnDismissListener { private static final String TAG = "EasyPopup"; private static final float DEFAULT_DIM = 0.7f; //PopupWindow对象 private PopupWindow mPopupWindow; //context private Context mContext; //contentView private View mContentView; //布局id private int mLayoutId; //获取焦点 private boolean mFocusable = true; //是否触摸之外dismiss private boolean mOutsideTouchable = true; //宽高 private int mWidth = ViewGroup.LayoutParams.MATCH_PARENT; private int mHeight = ViewGroup.LayoutParams.MATCH_PARENT; private int mAnimationStyle; private PopupWindow.OnDismissListener mOnDismissListener; //弹出pop时,背景是否变暗 private boolean isBackgroundDim; //背景变暗时透明度 private float mDimValue = DEFAULT_DIM; //背景变暗颜色 @ColorInt private int mDimColor = Color.BLACK; //背景变暗的view @NonNull private ViewGroup mDimView; private Transition mEnterTransition; private Transition mExitTransition; private boolean mFocusAndOutsideEnable = true; private View mAnchorView; @YGravity private int mYGravity = YGravity.BELOW; @XGravity private int mXGravity = XGravity.LEFT; private int mOffsetX; private int mOffsetY; private int mInputMethodMode = PopupWindow.INPUT_METHOD_FROM_FOCUSABLE; private int mSoftInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED; //是否重新测量宽高 private boolean isNeedReMeasureWH = false; //真实的宽高是否已经准备好 private boolean isRealWHAlready = false; private boolean isAtAnchorViewMethod = false; private OnRealWHAlreadyListener mOnRealWHAlreadyListener; protected T self() { //noinspection unchecked return (T) this; } public T apply() { if (mPopupWindow == null) { mPopupWindow = new PopupWindow(); } onPopupWindowCreated(); initContentViewAndWH(); onPopupWindowViewCreated(mContentView); if (mAnimationStyle != 0) { mPopupWindow.setAnimationStyle(mAnimationStyle); } initFocusAndBack(); mPopupWindow.setOnDismissListener(this); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (mEnterTransition != null) { mPopupWindow.setEnterTransition(mEnterTransition); } if (mExitTransition != null) { mPopupWindow.setExitTransition(mExitTransition); } } return self(); } private void initContentViewAndWH() { if (mContentView == null) { if (mLayoutId != 0 && mContext != null) { mContentView = LayoutInflater.from(mContext).inflate(mLayoutId, null); } else { throw new IllegalArgumentException("The content view is null,the layoutId=" + mLayoutId + ",context=" + mContext); } } mPopupWindow.setContentView(mContentView); if (mWidth > 0 || mWidth == ViewGroup.LayoutParams.WRAP_CONTENT || mWidth == ViewGroup.LayoutParams.MATCH_PARENT) { mPopupWindow.setWidth(mWidth); } else { mPopupWindow.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT); } if (mHeight > 0 || mHeight == ViewGroup.LayoutParams.WRAP_CONTENT || mHeight == ViewGroup.LayoutParams.MATCH_PARENT) { mPopupWindow.setHeight(mHeight); } else { mPopupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT); } //测量contentView大小 //可能不准 measureContentView(); //获取contentView的精准大小 registerOnGlobalLayoutListener(); mPopupWindow.setInputMethodMode(mInputMethodMode); mPopupWindow.setSoftInputMode(mSoftInputMode); } private void initFocusAndBack() { if (!mFocusAndOutsideEnable) { //from https://github.com/pinguo-zhouwei/CustomPopwindow mPopupWindow.setFocusable(true); mPopupWindow.setOutsideTouchable(false); mPopupWindow.setBackgroundDrawable(null); //注意下面这三个是contentView 不是PopupWindow,响应返回按钮事件 mPopupWindow.getContentView().setFocusable(true); mPopupWindow.getContentView().setFocusableInTouchMode(true); mPopupWindow.getContentView().setOnKeyListener(new View.OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { mPopupWindow.dismiss(); return true; } return false; } }); //在Android 6.0以上 ,只能通过拦截事件来解决 mPopupWindow.setTouchInterceptor(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { final int x = (int) event.getX(); final int y = (int) event.getY(); if ((event.getAction() == MotionEvent.ACTION_DOWN) && ((x < 0) || (x >= mWidth) || (y < 0) || (y >= mHeight))) { //outside Log.d(TAG, "onTouch outside:mWidth=" + mWidth + ",mHeight=" + mHeight); return true; } else if (event.getAction() == MotionEvent.ACTION_OUTSIDE) { //outside Log.d(TAG, "onTouch outside event:mWidth=" + mWidth + ",mHeight=" + mHeight); return true; } return false; } }); } else { mPopupWindow.setFocusable(mFocusable); mPopupWindow.setOutsideTouchable(mOutsideTouchable); mPopupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); } } /****自定义生命周期方法****/ /** * PopupWindow对象创建完成 */ protected void onPopupWindowCreated() { //执行设置PopupWindow属性也可以通过Builder中设置 //setContentView(x,x,x); //... initAttributes(); } protected void onPopupWindowViewCreated(View contentView) { initViews(contentView); } protected void onPopupWindowDismiss() { } /** * 可以在此方法中设置PopupWindow需要的属性 */ protected abstract void initAttributes(); /** * 初始化view {@see getView()} * * @param view */ protected abstract void initViews(View view); /** * 是否需要测量 contentView的大小 * 如果需要重新测量并为宽高赋值 * 注:此方法获取的宽高可能不准确 MATCH_PARENT时无法获取准确的宽高 */ private void measureContentView() { final View contentView = getContentView(); if (mWidth <= 0 || mHeight <= 0) { //测量大小 contentView.measure(0, View.MeasureSpec.UNSPECIFIED); if (mWidth <= 0) { mWidth = contentView.getMeasuredWidth(); } if (mHeight <= 0) { mHeight = contentView.getMeasuredHeight(); } } } /** * 注册GlobalLayoutListener 获取精准的宽高 */ private void registerOnGlobalLayoutListener() { getContentView().getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { getContentView().getViewTreeObserver().removeOnGlobalLayoutListener(this); mWidth = getContentView().getWidth(); mHeight = getContentView().getHeight(); isRealWHAlready = true; isNeedReMeasureWH = false; if (mOnRealWHAlreadyListener != null) { mOnRealWHAlreadyListener.onRealWHAlready(BasePopup.this, mWidth, mHeight, mAnchorView == null ? 0 : mAnchorView.getWidth(), mAnchorView == null ? 0 : mAnchorView.getHeight()); } // Log.d(TAG, "onGlobalLayout finished. isShowing=" + isShowing()); if (isShowing() && isAtAnchorViewMethod) { updateLocation(mWidth, mHeight, mAnchorView, mYGravity, mXGravity, mOffsetX, mOffsetY); } } }); } /** * 更新 PopupWindow 到精准的位置 * * @param width * @param height * @param anchor * @param yGravity * @param xGravity * @param x * @param y */ private void updateLocation(int width, int height, @NonNull View anchor, @YGravity final int yGravity, @XGravity int xGravity, int x, int y) { if (mPopupWindow == null) { return; } x = calculateX(anchor, xGravity, width, x); y = calculateY(anchor, yGravity, height, y); mPopupWindow.update(anchor, x, y, width, height); } /****设置属性方法****/ public T setContext(Context context) { this.mContext = context; return self(); } public T setContentView(View contentView) { this.mContentView = contentView; this.mLayoutId = 0; return self(); } public T setContentView(@LayoutRes int layoutId) { this.mContentView = null; this.mLayoutId = layoutId; return self(); } public T setContentView(Context context, @LayoutRes int layoutId) { this.mContext = context; this.mContentView = null; this.mLayoutId = layoutId; return self(); } public T setContentView(View contentView, int width, int height) { this.mContentView = contentView; this.mLayoutId = 0; this.mWidth = width; this.mHeight = height; return self(); } public T setContentView(@LayoutRes int layoutId, int width, int height) { this.mContentView = null; this.mLayoutId = layoutId; this.mWidth = width; this.mHeight = height; return self(); } public T setContentView(Context context, @LayoutRes int layoutId, int width, int height) { this.mContext = context; this.mContentView = null; this.mLayoutId = layoutId; this.mWidth = width; this.mHeight = height; return self(); } public T setWidth(int width) { this.mWidth = width; return self(); } public T setHeight(int height) { this.mHeight = height; return self(); } public T setAnchorView(View view) { this.mAnchorView = view; return self(); } public T setYGravity(@YGravity int yGravity) { this.mYGravity = yGravity; return self(); } public T setXGravity(@XGravity int xGravity) { this.mXGravity = xGravity; return self(); } public T setOffsetX(int offsetX) { this.mOffsetX = offsetX; return self(); } public T setOffsetY(int offsetY) { this.mOffsetY = offsetY; return self(); } public T setAnimationStyle(@StyleRes int animationStyle) { this.mAnimationStyle = animationStyle; return self(); } public T setFocusable(boolean focusable) { this.mFocusable = focusable; return self(); } public T setOutsideTouchable(boolean outsideTouchable) { this.mOutsideTouchable = outsideTouchable; return self(); } /** * 是否可以点击PopupWindow之外的地方dismiss * * @param focusAndOutsideEnable * @return */ public T setFocusAndOutsideEnable(boolean focusAndOutsideEnable) { this.mFocusAndOutsideEnable = focusAndOutsideEnable; return self(); } /** * 背景变暗支持api>=18 * * @param isDim * @return */ public T setBackgroundDimEnable(boolean isDim) { this.isBackgroundDim = isDim; return self(); } public T setDimValue(@FloatRange(from = 0.0f, to = 1.0f) float dimValue) { this.mDimValue = dimValue; return self(); } public T setDimColor(@ColorInt int color) { this.mDimColor = color; return self(); } public T setDimView(@NonNull ViewGroup dimView) { this.mDimView = dimView; return self(); } @RequiresApi(api = Build.VERSION_CODES.M) public T setEnterTransition(Transition enterTransition) { this.mEnterTransition = enterTransition; return self(); } @RequiresApi(api = Build.VERSION_CODES.M) public T setExitTransition(Transition exitTransition) { this.mExitTransition = exitTransition; return self(); } public T setInputMethodMode(int mode) { this.mInputMethodMode = mode; return self(); } public T setSoftInputMode(int mode) { this.mSoftInputMode = mode; return self(); } /** * 是否需要重新获取宽高 * * @param needReMeasureWH * @return */ public T setNeedReMeasureWH(boolean needReMeasureWH) { this.isNeedReMeasureWH = needReMeasureWH; return self(); } /** * 检查是否调用了 apply() 方法 * * @param isAtAnchorView 是否是 showAt */ private void checkIsApply(boolean isAtAnchorView) { if (this.isAtAnchorViewMethod != isAtAnchorView) { this.isAtAnchorViewMethod = isAtAnchorView; } if (mPopupWindow == null) { apply(); } } /** * 使用此方法需要在创建的时候调用setAnchorView()等属性设置{@see setAnchorView()} */ public void showAsDropDown() { if (mAnchorView == null) { return; } showAsDropDown(mAnchorView, mOffsetX, mOffsetY); } /** * PopupWindow自带的显示方法 * * @param anchor * @param offsetX * @param offsetY */ public void showAsDropDown(View anchor, int offsetX, int offsetY) { //防止忘记调用 apply() 方法 checkIsApply(false); handleBackgroundDim(); mAnchorView = anchor; mOffsetX = offsetX; mOffsetY = offsetY; //是否重新获取宽高 if (isNeedReMeasureWH) { registerOnGlobalLayoutListener(); } mPopupWindow.showAsDropDown(anchor, mOffsetX, mOffsetY); } public void showAsDropDown(View anchor) { //防止忘记调用 apply() 方法 checkIsApply(false); handleBackgroundDim(); mAnchorView = anchor; //是否重新获取宽高 if (isNeedReMeasureWH) { registerOnGlobalLayoutListener(); } mPopupWindow.showAsDropDown(anchor); } @RequiresApi(api = Build.VERSION_CODES.KITKAT) public void showAsDropDown(View anchor, int offsetX, int offsetY, int gravity) { //防止忘记调用 apply() 方法 checkIsApply(false); handleBackgroundDim(); mAnchorView = anchor; mOffsetX = offsetX; mOffsetY = offsetY; //是否重新获取宽高 if (isNeedReMeasureWH) { registerOnGlobalLayoutListener(); } PopupWindowCompat.showAsDropDown(mPopupWindow, anchor, mOffsetX, mOffsetY, gravity); } public void showAtLocation(View parent, int gravity, int offsetX, int offsetY) { //防止忘记调用 apply() 方法 checkIsApply(false); handleBackgroundDim(); mAnchorView = parent; mOffsetX = offsetX; mOffsetY = offsetY; //是否重新获取宽高 if (isNeedReMeasureWH) { registerOnGlobalLayoutListener(); } mPopupWindow.showAtLocation(parent, gravity, mOffsetX, mOffsetY); } /*** * * @param anchor * @param addheight 添加的高度 * @param addFoxx Y的偏移量 */ public void showAsDropDownmain(View anchor,int addheight,int addFoxx) { //防止忘记调用 apply() 方法 checkIsApply(false); // handleBackgroundDim(); mAnchorView = anchor; //是否重新获取宽高 if (isNeedReMeasureWH) { registerOnGlobalLayoutListener(); } int bottomHeight = BottomBarUtils.getInstans().getNavigationBarHeightIfRoom((Activity) mContext); Log.i(TAG, "showAsDropDownmain: bottomHeight=="+bottomHeight+""); if (Build.VERSION.SDK_INT >= 24) { Rect rect = new Rect(); anchor.getGlobalVisibleRect(rect); int h = anchor.getResources().getDisplayMetrics().heightPixels - rect.bottom; // setHeight(h); mPopupWindow.setHeight(h+addheight); mPopupWindow.showAsDropDown(anchor,0,bottomHeight+addFoxx); return; } mPopupWindow.showAsDropDown(anchor,0,addFoxx); } public void showAsDropDownmain(View anchor) { //防止忘记调用 apply() 方法 checkIsApply(false); // handleBackgroundDim(); mAnchorView = anchor; //是否重新获取宽高 if (isNeedReMeasureWH) { registerOnGlobalLayoutListener(); } int bottomHeight = BottomBarUtils.getInstans().getNavigationBarHeightIfRoom((Activity) mContext); Log.i(TAG, "showAsDropDownmain: bottomHeight=="+bottomHeight+""); if (Build.VERSION.SDK_INT >= 24) { Rect rect = new Rect(); anchor.getGlobalVisibleRect(rect); int h = anchor.getResources().getDisplayMetrics().heightPixels - rect.bottom; // setHeight(h); mPopupWindow.setHeight(h); mPopupWindow.showAsDropDown(anchor,0,bottomHeight); return; } mPopupWindow.showAsDropDown(anchor); } /** * 相对anchor view显示 *

* 使用此方法需要在创建的时候调用setAnchorView()等属性设置{@see setAnchorView()} *

* 注意:如果使用 VerticalGravity 和 HorizontalGravity 时,请确保使用之后 PopupWindow 没有超出屏幕边界, * 如果超出屏幕边界,VerticalGravity 和 HorizontalGravity 可能无效,从而达不到你想要的效果。 */ public void showAtAnchorView() { if (mAnchorView == null) { return; } showAtAnchorView(mAnchorView, mYGravity, mXGravity); } /** * 相对anchor view显示,适用 宽高不为match_parent *

* 注意:如果使用 VerticalGravity 和 HorizontalGravity 时,请确保使用之后 PopupWindow 没有超出屏幕边界, * 如果超出屏幕边界,VerticalGravity 和 HorizontalGravity 可能无效,从而达不到你想要的效果。 * * * @param anchor * @param vertGravity * @param horizGravity */ public void showAtAnchorView(@NonNull View anchor, @YGravity int vertGravity, @XGravity int horizGravity) { showAtAnchorView(anchor, vertGravity, horizGravity, 0, 0); } /** * 相对anchor view显示,适用 宽高不为match_parent *

* 注意:如果使用 VerticalGravity 和 HorizontalGravity 时,请确保使用之后 PopupWindow 没有超出屏幕边界, * 如果超出屏幕边界,VerticalGravity 和 HorizontalGravity 可能无效,从而达不到你想要的效果。 * * @param anchor * @param vertGravity 垂直方向的对齐方式 * @param horizGravity 水平方向的对齐方式 * @param x 水平方向的偏移 * @param y 垂直方向的偏移 */ public void showAtAnchorView(@NonNull View anchor, @YGravity final int vertGravity, @XGravity int horizGravity, int x, int y) { //防止忘记调用 apply() 方法 checkIsApply(true); mAnchorView = anchor; mOffsetX = x; mOffsetY = y; mYGravity = vertGravity; mXGravity = horizGravity; //处理背景变暗 handleBackgroundDim(); x = calculateX(anchor, horizGravity, mWidth, mOffsetX); y = calculateY(anchor, vertGravity, mHeight, mOffsetY); //是否重新获取宽高 if (isNeedReMeasureWH) { registerOnGlobalLayoutListener(); } // Log.i(TAG, "showAtAnchorView: w=" + measuredW + ",y=" + measuredH); PopupWindowCompat.showAsDropDown(mPopupWindow, anchor, x, y, Gravity.NO_GRAVITY); } /** * 根据垂直gravity计算y偏移 * * @param anchor * @param vertGravity * @param measuredH * @param y * @return */ private int calculateY(View anchor, int vertGravity, int measuredH, int y) { switch (vertGravity) { case YGravity.ABOVE: //anchor view之上 y -= measuredH + anchor.getHeight(); break; case YGravity.ALIGN_BOTTOM: //anchor view底部对齐 y -= measuredH; break; case YGravity.CENTER: //anchor view垂直居中 y -= anchor.getHeight() / 2 + measuredH / 2; break; case YGravity.ALIGN_TOP: //anchor view顶部对齐 y -= anchor.getHeight(); break; case YGravity.BELOW: //anchor view之下 // Default position. break; } return y; } /** * 根据水平gravity计算x偏移 * * @param anchor * @param horizGravity * @param measuredW * @param x * @return */ private int calculateX(View anchor, int horizGravity, int measuredW, int x) { switch (horizGravity) { case XGravity.LEFT: //anchor view左侧 x -= measuredW; break; case XGravity.ALIGN_RIGHT: //与anchor view右边对齐 x -= measuredW - anchor.getWidth(); break; case XGravity.CENTER: //anchor view水平居中 x += anchor.getWidth() / 2 - measuredW / 2; break; case XGravity.ALIGN_LEFT: //与anchor view左边对齐 // Default position. break; case XGravity.RIGHT: //anchor view右侧 x += anchor.getWidth(); break; } return x; } /** * 设置监听器 * * @param listener */ public T setOnDismissListener(PopupWindow.OnDismissListener listener) { this.mOnDismissListener = listener; return self(); } public T setOnRealWHAlreadyListener(OnRealWHAlreadyListener listener) { this.mOnRealWHAlreadyListener = listener; return self(); } /** * 处理背景变暗 * https://blog.nex3z.com/2016/12/04/%E5%BC%B9%E5%87%BApopupwindow%E5%90%8E%E8%AE%A9%E8%83%8C%E6%99%AF%E5%8F%98%E6%9A%97%E7%9A%84%E6%96%B9%E6%B3%95/ */ private void handleBackgroundDim() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { if (!isBackgroundDim) { return; } if (mDimView != null) { applyDim(mDimView); } else { if (getContentView() != null && getContentView().getContext() != null && getContentView().getContext() instanceof Activity) { Activity activity = (Activity) getContentView().getContext(); applyDim(activity); } } } } @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2) private void applyDim(Activity activity) { ViewGroup parent = (ViewGroup) activity.getWindow().getDecorView().getRootView(); //activity跟布局 // ViewGroup parent = (ViewGroup) parent1.getChildAt(0); Drawable dimDrawable = new ColorDrawable(mDimColor); dimDrawable.setBounds(0, 0, parent.getWidth(), parent.getHeight()); dimDrawable.setAlpha((int) (255 * mDimValue)); ViewGroupOverlay overlay = parent.getOverlay(); overlay.add(dimDrawable); } @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2) private void applyDim(ViewGroup dimView) { Drawable dimDrawable = new ColorDrawable(mDimColor); dimDrawable.setBounds(0, 0, dimView.getWidth(), dimView.getHeight()); dimDrawable.setAlpha((int) (255 * mDimValue)); ViewGroupOverlay overlay = dimView.getOverlay(); overlay.add(dimDrawable); } /** * 清除背景变暗 */ private void clearBackgroundDim() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { if (isBackgroundDim) { if (mDimView != null) { clearDim(mDimView); } else { if (getContentView() != null) { Activity activity = (Activity) getContentView().getContext(); if (activity != null) { clearDim(activity); } } } } } } @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2) private void clearDim(Activity activity) { ViewGroup parent = (ViewGroup) activity.getWindow().getDecorView().getRootView(); //activity跟布局 // ViewGroup parent = (ViewGroup) parent1.getChildAt(0); ViewGroupOverlay overlay = parent.getOverlay(); overlay.clear(); } @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2) private void clearDim(ViewGroup dimView) { ViewGroupOverlay overlay = dimView.getOverlay(); overlay.clear(); } /** * 获取PopupWindow中加载的view * * @return */ public View getContentView() { if (mPopupWindow != null) { return mPopupWindow.getContentView(); } else { return null; } } /** * 获取PopupWindow对象 * * @return */ public PopupWindow getPopupWindow() { return mPopupWindow; } /** * 获取PopupWindow 宽 * * @return */ public int getWidth() { return mWidth; } /** * 获取PopupWindow 高 * * @return */ public int getHeight() { return mHeight; } /** * 获取纵向Gravity * * @return */ public int getXGravity() { return mXGravity; } /** * 获取横向Gravity * * @return */ public int getYGravity() { return mYGravity; } /** * 获取x轴方向的偏移 * * @return */ public int getOffsetX() { return mOffsetX; } /** * 获取y轴方向的偏移 * * @return */ public int getOffsetY() { return mOffsetY; } /** * 是否正在显示 * * @return */ public boolean isShowing() { return mPopupWindow != null && mPopupWindow.isShowing(); } /** * 是否精准的宽高获取完成 * * @return */ public boolean isRealWHAlready() { return isRealWHAlready; } /** * 获取view * * @param viewId * @param * @return */ public T findViewById(@IdRes int viewId) { View view = null; if (getContentView() != null) { view = getContentView().findViewById(viewId); } return (T) view; } /** * 消失 */ public void dismiss() { if (mPopupWindow != null) { mPopupWindow.dismiss(); } } @Override public void onDismiss() { handleDismiss(); } /** * PopupWindow消失后处理一些逻辑 */ private void handleDismiss() { if (mOnDismissListener != null) { mOnDismissListener.onDismiss(); } //清除背景变暗 clearBackgroundDim(); if (mPopupWindow != null && mPopupWindow.isShowing()) { mPopupWindow.dismiss(); } onPopupWindowDismiss(); } /** * PopupWindow是否显示在window中 * 用于获取准确的PopupWindow宽高,可以重新设置偏移量 */ public interface OnRealWHAlreadyListener { /** * 在 show方法之后 updateLocation之前执行 * * @param popWidth PopupWindow准确的宽 * @param popHeight PopupWindow准确的高 * @param anchorW 锚点View宽 * @param anchorH 锚点View高 */ void onRealWHAlready(BasePopup basePopup, int popWidth, int popHeight, int anchorW, int anchorH); } }