Android 自定义PopupWindow

封装一个通用PopupWindow,避免重复造轮子,简化代码,方便管理。

这里写图片描述

自定义PopupWindow:详情看注释

public class CommonPopWindow {
    private static PopupWindow mPopupWindow;
    private static Builder mBuilder;
    private static View mContentView;
    private static Window mWindow;

    public interface ViewClickListener {
        void getChildView(PopupWindow mPopupWindow, View view, int mLayoutResId);
    }

    private CommonPopWindow() {
        mBuilder = new Builder();
    }

    public static Builder newBuilder() {
        if (mBuilder == null) {
            mBuilder = new Builder();
        }
        return mBuilder;
    }

    /**
     * 获取PopupWindow宽度
     *
     * @return
     */
    public int getWidth() {
        if (mPopupWindow != null) {
            return mContentView.getMeasuredWidth();
        }
        return 0;
    }


    /**
     * 获取PopupWindow高度
     *
     * @return
     */
    public int getHeight() {
        if (mPopupWindow != null) {
            return mContentView.getMeasuredHeight();
        }
        return 0;
    }

    /**
     * 显示在控件的下方
     */
    public CommonPopWindow showDownPop(View parent) {
        if (parent.getVisibility() == View.GONE) {
            mPopupWindow.showAtLocation(parent, Gravity.NO_GRAVITY, 0, 0);
        } else {
            int[] location = new int[2];
            parent.getLocationOnScreen(location);
            if (mPopupWindow != null) {
                mPopupWindow.showAtLocation(parent, Gravity.NO_GRAVITY, location[0], location[1] + parent.getHeight());
            }
        }
        return this;
    }

    /**
     * 显示在控件的上方
     */
    public CommonPopWindow showAsUp(View view) {
        if (view.getVisibility() == View.GONE) {
            mPopupWindow.showAtLocation(view, Gravity.NO_GRAVITY, 0, 0);
        } else {
            int[] location = new int[2];
            view.getLocationOnScreen(location);
            if (mPopupWindow != null) {
                mPopupWindow.showAtLocation(view, Gravity.NO_GRAVITY, location[0], location[1] - view.getHeight());
                //方式二
//                mPopupWindow.showAsDropDown(view, 0, -(getHeight() + view.getMeasuredHeight()));
            }
        }
        return this;
    }

    /**
     * 显示在控件的左边
     */
    public CommonPopWindow showAsLeft(View view) {
        if (view.getVisibility() == View.GONE) {
            mPopupWindow.showAtLocation(view, Gravity.NO_GRAVITY, 0, 0);
        } else {
            int[] location = new int[2];
            view.getLocationOnScreen(location);
            if (mPopupWindow != null) {
                mPopupWindow.showAtLocation(view, Gravity.NO_GRAVITY, location[0] - getWidth(), location[1]);
            }
        }
        return this;
    }

    /**
     * 显示在控件右边
     */
    public CommonPopWindow showAsRight(View view) {
        if (view.getVisibility() == View.GONE) {
            mPopupWindow.showAtLocation(view, Gravity.NO_GRAVITY, 0, 0);
        } else {
            int[] location = new int[2];
            view.getLocationOnScreen(location);
            if (mPopupWindow != null) {
                mPopupWindow.showAtLocation(view, Gravity.NO_GRAVITY, location[0] + view.getWidth(), location[1]);
            }
        }
        return this;
    }

    /**
     * 显示控件下方
     *
     * @param view
     * @return
     */
    public CommonPopWindow showAsDown(View view) {
        if (mPopupWindow != null) {
            mPopupWindow.showAsDropDown(view);
        }
        return this;
    }

    /**
     * 全屏弹出
     */
    public CommonPopWindow showAsBottom(View view) {
        if (view.getVisibility() == View.GONE) {
            mPopupWindow.showAtLocation(view, Gravity.NO_GRAVITY, 0, 0);
        } else {
            int[] location = new int[2];
            view.getLocationOnScreen(location);
            if (mPopupWindow != null) {
                mPopupWindow.showAtLocation(view, Gravity.BOTTOM, 0, 0);
            }
        }
        return this;
    }

    public CommonPopWindow showAtLocation(View anchor, int gravity, int x, int y) {
        if (mPopupWindow != null) {
            mPopupWindow.showAtLocation(anchor, gravity, x, y);
        }
        return this;
    }

    /**
     * 取消
     */
    public static void dismiss() {
        if (mWindow != null) {
            WindowManager.LayoutParams params = mWindow.getAttributes();
            params.alpha = 1.0f;
            mWindow.setAttributes(params);
        }
        if (mPopupWindow != null && mPopupWindow.isShowing())
            mPopupWindow.dismiss();
    }

    /*
     * ---------------------Builder-------------------------
     */
    public static class Builder implements PopupWindow.OnDismissListener {
        private Context mContext;
        private int mLayoutResId;//布局ID
        private int mWidth, mHeight;//弹窗宽高
        private int mAnimationStyle;//动画样式
        private ViewClickListener mListener;//子View监听回调
        private Drawable mDrawable;//背景Drawable
        private boolean mTouchable = true;//是否相应touch事件
        private boolean mFocusable = true;//是否获取焦点
        private boolean mOutsideTouchable = true;//设置外部是否点击
        private boolean mBackgroundDarkEnable = false;//是否背景窗体变暗
        private float mDarkAlpha = 1.0f;//透明值

        public CommonPopWindow build(Context context) {
            this.mContext = context;
            CommonPopWindow popWindow = new CommonPopWindow();
            apply();
            if (mListener != null && mLayoutResId != 0) {
                mListener.getChildView(mPopupWindow, mContentView, mLayoutResId);
            }
            return popWindow;
        }

        private void apply() {
            if (mLayoutResId != 0) {
                mContentView = LayoutInflater.from(mContext).inflate(mLayoutResId, null);
            }
            if (mWidth != 0 && mHeight != 0) {
                mPopupWindow = new PopupWindow(mContentView, mWidth, mHeight);
            } else {
                mPopupWindow = new PopupWindow(mContentView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            }

            mPopupWindow.setTouchable(mTouchable);
            mPopupWindow.setFocusable(mFocusable);
            mPopupWindow.setOutsideTouchable(mOutsideTouchable);

            if (mDrawable != null) {
                mPopupWindow.setBackgroundDrawable(mDrawable);
            } else {
                mPopupWindow.setBackgroundDrawable(new ColorDrawable());
            }
            if (mAnimationStyle != -1) {
                mPopupWindow.setAnimationStyle(mAnimationStyle);
            }
            if (mWidth == 0 || mHeight == 0) {
                measureWidthAndHeight(mContentView);
                //如果没有设置高度的情况下,设置宽高并赋值
                mWidth = mPopupWindow.getContentView().getMeasuredWidth();
                mHeight = mPopupWindow.getContentView().getMeasuredHeight();
            }

            Activity activity = (Activity) mContext;
            if (activity != null && mBackgroundDarkEnable) {
                float alpha = (mDarkAlpha >= 0f || mDarkAlpha <= 1f) ? mDarkAlpha : 0.7f;
                mWindow = activity.getWindow();
                WindowManager.LayoutParams params = mWindow.getAttributes();
                params.alpha = alpha;
                mWindow.setAttributes(params);
            }

            mPopupWindow.setOnDismissListener(this);

            mPopupWindow.update();
        }

        @Override
        public void onDismiss() {
            dismiss();
        }

        /**
         * 测量View的宽高
         *
         * @param mContentView
         */
        private void measureWidthAndHeight(View mContentView) {
            int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec((1 << 30) - 1, View.MeasureSpec.AT_MOST);
            int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec((1 << 30) - 1, View.MeasureSpec.AT_MOST);
            mContentView.measure(widthMeasureSpec, heightMeasureSpec);
        }

        /**
         * 设置布局ID
         *
         * @param layoutResId
         * @return
         */
        public Builder setView(@LayoutRes int layoutResId) {
            mContentView = null;
            this.mLayoutResId = layoutResId;
            return this;
        }

        /**
         * 设置宽高
         *
         * @param width
         * @param height
         * @return
         */
        public Builder setSize(int width, int height) {
            mWidth = width;
            mHeight = height;
            return this;
        }

        /**
         * 设置背景
         *
         * @param drawable
         * @return
         */
        public Builder setBackgroundDrawable(Drawable drawable) {
            mDrawable = drawable;
            return this;
        }

        /**
         * 设置背景是否变暗
         *
         * @param darkEnable
         * @return
         */
        public Builder setBackgroundDarkEnable(boolean darkEnable) {
            mBackgroundDarkEnable = darkEnable;
            return this;
        }

        /**
         * 设置背景透明度
         *
         * @param dackAlpha
         * @return
         */
        public Builder setBackgroundAlpha(@FloatRange(from = 0.0, to = 1.0) float dackAlpha) {
            mDarkAlpha = dackAlpha;
            return this;
        }

        /**
         * 是否点击Outside消失
         *
         * @param touchable
         * @return
         */
        public Builder setOutsideTouchable(boolean touchable) {
            mOutsideTouchable = touchable;
            return this;
        }

        /**
         * 是否设置Touch事件
         *
         * @param touchable
         * @return
         */
        public Builder setTouchable(boolean touchable) {
            mTouchable = touchable;
            return this;
        }

        /**
         * 设置动画
         *
         * @param animationStyle
         * @return
         */
        public Builder setAnimationStyle(@StyleRes int animationStyle) {
            mAnimationStyle = animationStyle;
            return this;
        }

        /**
         * 是否设置获取焦点
         *
         * @param focusable
         * @return
         */
        public Builder setFocusable(boolean focusable) {
            mFocusable = focusable;
            return this;
        }

        /**
         * 设置子View点击事件回调
         *
         * @param listener
         * @return
         */
        public Builder setViewOnClickListener(ViewClickListener listener) {
            this.mListener = listener;
            return this;
        }
    }
}

使用PopupWindow

public class MainActivity extends AppCompatActivity implements CommonPopWindow.ViewClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    //向上弹出
    public void showUpPopClick(View view) {
        CommonPopWindow.newBuilder()
                .setView(R.layout.pop_right_or_left)
                .setViewOnClickListener(this)
                .build(this)
                .showAsUp(view);
    }

    //向下弹出
    public void showDownPopClick(View view) {
        CommonPopWindow.newBuilder()
                .setView(R.layout.pop_right_or_left)
                .setViewOnClickListener(this)
                .build(this)
                .showAsDown(view);
    }

    //向左弹出
    public void showLeftPopClick(View view) {
        CommonPopWindow.newBuilder()
                .setView(R.layout.pop_right_or_left)
                .setAnimationStyle(R.style.AnimRightToLeft)
                .setViewOnClickListener(this)
                .build(this)
                .showAsLeft(view);
    }

    //向右弹出
    public void showRightPopClick(View view) {
        CommonPopWindow.newBuilder()
                .setView(R.layout.pop_right_or_left)
                .setAnimationStyle(R.style.AnimRightToLeft)
                .setViewOnClickListener(this)
                .build(this)
                .showAsRight(view);
    }

    //底部弹出
    public void showBottomPopClick(View view) {
        CommonPopWindow.newBuilder()
                .setView(R.layout.pop_bottom)
                .setAnimationStyle(R.style.AnimUp)
                .setBackgroundDrawable(new BitmapDrawable())
                .setSize(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
                .setViewOnClickListener(this)
                .setBackgroundDarkEnable(true)
                .setBackgroundAlpha(0.7f)
                .build(this)
                .showAsBottom(view);
    }

    @Override
    public void getChildView(final PopupWindow mPopupWindow, View view, int layoutResId) {
        switch (layoutResId) {
            case R.layout.pop_right_or_left:
                ImageView good = (ImageView) view.findViewById(R.id.good);
                ImageView collection = (ImageView) view.findViewById(R.id.collection);
                good.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        toast("点赞");
                        Log.e("Tag", "onClick");
                        mPopupWindow.dismiss();
                    }
                });
                collection.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        toast("收藏");
                        mPopupWindow.dismiss();
                    }
                });
                break;
            case R.layout.pop_bottom:
                Button btnTakePhoto = (Button) view.findViewById(R.id.btn_take_photo);
                Button btnSelectPhoto = (Button) view.findViewById(R.id.btn_select_photo);
                Button btnCancel = (Button) view.findViewById(R.id.btn_cancel);
                btnTakePhoto.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        toast("拍照");
                        mPopupWindow.dismiss();
                    }
                });
                btnSelectPhoto.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        toast("相册选取");
                        mPopupWindow.dismiss();
                    }
                });
                btnCancel.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        toast("取消");
                        mPopupWindow.dismiss();
                    }
                });
                break;
        }
    }

    private void toast(String str) {
        Toast.makeText(this, str, Toast.LENGTH_SHORT).show();
    }
}

代码下载

猜你喜欢

转载自blog.csdn.net/qq_14876133/article/details/81018545
今日推荐