美文网首页Android UI学习之鸿蒙&Android
Android 小技巧之通用 PopupWindow

Android 小技巧之通用 PopupWindow

作者: Kevin_小飞象 | 来源:发表于2021-06-23 16:16 被阅读0次
    每日一图.jpg

    Android 中的弹窗基本有两种,一种是AlertDialog,另一种是PopupWindow。AlertDialog 的显示位置是固定的,PopWindow 的显示位置是我们可以设置和调整的,因此,像项目中的一些场景如:某个功能的提示说明、点击按钮在按钮上方或者下方弹出菜单、新功能弹窗引导等。

    API

    1. 构造函数
    public PopupWindow(int width, int height)
    
    public PopupWindow(View contentView, int width, int height) 
    
    public PopupWindow(View contentView, int width, int height, boolean focusable)
    
    1. 设置显示的View
    public void setContentView(View contentView)
    
    1. 设置展示的宽、高
    // 设置宽
    public void setWidth(int width)
    //设置高
    public void setHeight(int height)
    
    1. 设置是否获取焦点
    public void setFocusable(boolean focusable)
    
    1. 设置点击外区域是否隐藏 PopupWindow
    public void setOutsideTouchable(boolean touchable)
    
    1. 隐藏
    public void dismiss()
    
    1. 设置dissmiss 回调监听
    public void setOnDismissListener(OnDismissListener onDismissListener)
    
    1. 显示 PopupWindow
    //直接显示在参照View 的左下方
    public void showAsDropDown(View anchor)
    // 显示在参照View的左下方,可以通过xoff,yOff,来调节x,y方向的偏移
    public void showAsDropDown(View anchor, int xoff, int off)
    
    public void showAsDropDown(View anchor, int xoff, int yoff, int gravity)
    //显示在指定位置,相对于整个屏幕的window而言,通过gravity调解显示在左、上、右、下、中. x,y调整两个方向的偏移
    public void showAtLocation(View parent, int gravity, int x, int y) 
    

    源码

    public class CustomPopWindow {
        private Context mContext;
        private int mWidth;
        private int mHeight;
        private boolean mIsFocusable = true;
        private boolean mIsOutside = true;
        private int mResLayoutId = -1;
        private View mContentView;
        private PopupWindow mPopupWindow;
        private int mAnimationStyle = -1;
    
        private boolean mClippEnable = true;//default is true
        private boolean mIgnoreCheekPress = false;
        private int mInputMode = -1;
        private PopupWindow.OnDismissListener mOnDismissListener;
        private int mSoftInputMode = -1;
        private boolean mTouchable = true;//default is ture
        private View.OnTouchListener mOnTouchListener;
        private CustomPopWindow(Context context){
            mContext = context;
        }
    
        public int getWidth() {
            return mWidth;
        }
    
        public int getHeight() {
            return mHeight;
        }
    
        /**
         *
         * @param anchor
         * @param xOff
         * @param yOff
         * @return
         */
        public CustomPopWindow showAsDropDown(View anchor, int xOff, int yOff){
            if(mPopupWindow!=null){
                mPopupWindow.showAsDropDown(anchor,xOff,yOff);
            }
            return this;
        }
    
        public CustomPopWindow showAsDropDown(View anchor){
            if(mPopupWindow!=null){
                mPopupWindow.showAsDropDown(anchor);
            }
            return this;
        }
    
        @RequiresApi(api = Build.VERSION_CODES.KITKAT)
        public CustomPopWindow showAsDropDown(View anchor, int xOff, int yOff, int gravity){
            if(mPopupWindow!=null){
                mPopupWindow.showAsDropDown(anchor,xOff,yOff,gravity);
            }
            return this;
        }
    
    
        /**
         * 相对于父控件的位置(通过设置Gravity.CENTER,下方Gravity.BOTTOM等 ),可以设置具体位置坐标
         * @param parent
         * @param gravity
         * @param x the popup's x location offset
         * @param y the popup's y location offset
         * @return
         */
        public CustomPopWindow showAtLocation(View parent, int gravity, int x, int y){
            if(mPopupWindow!=null){
                mPopupWindow.showAtLocation(parent,gravity,x,y);
            }
            return this;
        }
    
        /**
         * 添加一些属性设置
         * @param popupWindow
         */
        private void apply(PopupWindow popupWindow){
            popupWindow.setClippingEnabled(mClippEnable);
            if(mIgnoreCheekPress){
                popupWindow.setIgnoreCheekPress();
            }
            if(mInputMode!=-1){
                popupWindow.setInputMethodMode(mInputMode);
            }
            if(mSoftInputMode!=-1){
                popupWindow.setSoftInputMode(mSoftInputMode);
            }
            if(mOnDismissListener!=null){
                popupWindow.setOnDismissListener(mOnDismissListener);
            }
            if(mOnTouchListener!=null){
                popupWindow.setTouchInterceptor(mOnTouchListener);
            }
            popupWindow.setTouchable(mTouchable);
    
    
    
        }
    
        private PopupWindow build(){
    
            if(mContentView == null){
                mContentView = LayoutInflater.from(mContext).inflate(mResLayoutId,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);
            }
            if(mAnimationStyle!=-1){
                mPopupWindow.setAnimationStyle(mAnimationStyle);
            }
    
            apply(mPopupWindow);//设置一些属性
    
            mPopupWindow.setFocusable(mIsFocusable);
            mPopupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
            mPopupWindow.setOutsideTouchable(mIsOutside);
    
            if(mWidth == 0 || mHeight == 0){
                mPopupWindow.getContentView().measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
                //如果外面没有设置宽高的情况下,计算宽高并赋值
                mWidth = mPopupWindow.getContentView().getMeasuredWidth();
                mHeight = mPopupWindow.getContentView().getMeasuredHeight();
            }
    
            mPopupWindow.update();
    
            return mPopupWindow;
        }
    
        /**
         * 关闭popWindow
         */
        public void dissmiss(){
            if(mPopupWindow!=null){
                mPopupWindow.dismiss();
            }
        }
    
    
        public static class PopupWindowBuilder{
            private CustomPopWindow mCustomPopWindow;
    
            public PopupWindowBuilder(Context context){
                mCustomPopWindow = new CustomPopWindow(context);
            }
            public PopupWindowBuilder size(int width,int height){
                mCustomPopWindow.mWidth = width;
                mCustomPopWindow.mHeight = height;
                return this;
            }
    
    
            public PopupWindowBuilder setFocusable(boolean focusable){
                mCustomPopWindow.mIsFocusable = focusable;
                return this;
            }
    
    
    
            public PopupWindowBuilder setView(int resLayoutId){
                mCustomPopWindow.mResLayoutId = resLayoutId;
                mCustomPopWindow.mContentView = null;
                return this;
            }
    
            public PopupWindowBuilder setView(View view){
                mCustomPopWindow.mContentView = view;
                mCustomPopWindow.mResLayoutId = -1;
                return this;
            }
    
            public PopupWindowBuilder setOutsideTouchable(boolean outsideTouchable){
                mCustomPopWindow.mIsOutside = outsideTouchable;
                return this;
            }
    
            /**
             * 设置弹窗动画
             * @param animationStyle
             * @return
             */
            public PopupWindowBuilder setAnimationStyle(int animationStyle){
                mCustomPopWindow.mAnimationStyle = animationStyle;
                return this;
            }
    
    
            public PopupWindowBuilder setClippingEnable(boolean enable){
                mCustomPopWindow.mClippEnable =enable;
                return this;
            }
    
    
            public PopupWindowBuilder setIgnoreCheekPress(boolean ignoreCheekPress){
                mCustomPopWindow.mIgnoreCheekPress = ignoreCheekPress;
                return this;
            }
    
            public PopupWindowBuilder setInputMethodMode(int mode){
                mCustomPopWindow.mInputMode = mode;
                return this;
            }
    
            public PopupWindowBuilder setOnDissmissListener(PopupWindow.OnDismissListener onDissmissListener){
                mCustomPopWindow.mOnDismissListener = onDissmissListener;
                return this;
            }
    
    
            public PopupWindowBuilder setSoftInputMode(int softInputMode){
                mCustomPopWindow.mSoftInputMode = softInputMode;
                return this;
            }
    
    
            public PopupWindowBuilder setTouchable(boolean touchable){
                mCustomPopWindow.mTouchable = touchable;
                return this;
            }
    
            public PopupWindowBuilder setTouchIntercepter(View.OnTouchListener touchIntercepter){
                mCustomPopWindow.mOnTouchListener = touchIntercepter;
                return this;
            }
    
    
            public CustomPopWindow create(){
                //构建PopWindow
                mCustomPopWindow.build();
                return mCustomPopWindow;
            }
    
        }
    }
    

    使用

    public class MainActivity extends BaseActivity {
        @BindView(R.id.show_top)
        Button mShowTop;
    
        @BindView(R.id.show_center)
        Button mShowCenter;
    
        @BindView(R.id.show_bottom)
        Button mShowBottom;
    
        @BindView(R.id.show_left)
        Button mShowLeft;
    
        @BindView(R.id.show_right)
        Button mShowRignt;
    
        private CustomPopWindow mPopupWindow;
    
    
        @OnClick({R.id.show_top,R.id.show_center,R.id.show_bottom,R.id.show_left,R.id.show_right})
        public void onClicked(View view) {
            switch (view.getId()) {
                case R.id.show_top:
                    showBottom();
                    break;
    
                case R.id.show_center:
    
                    break;
    
                case R.id.show_bottom:
                    showSelectPhoto();
                    break;
    
                case R.id.show_left:
                    showLeft();
                    break;
    
                case R.id.show_right:
                    showRight();
                    break;
    
                default:
                    break;
            }
        }
    
        @Override
        public int getLayoutId() {
            return R.layout.activity_main;
        }
    
        @Override
        public void initView() {
    
        }
    
        private void showBottom() {
            View contentView = LayoutInflater.from(this).inflate(R.layout.popup_left_or_right,null);
            handleBottom(contentView);
            PopUtils.setBackgroundAlpha(MainActivity.this, 0.4f);
            mPopupWindow = new CustomPopWindow.PopupWindowBuilder(this)
                    .setView(contentView)
                    .size(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT)
                    .setFocusable(true)
                    .setOutsideTouchable(true)
                    .setAnimationStyle(R.style.AnimDown)
                    .setOnDissmissListener(new PopupWindow.OnDismissListener() {
                        @Override
                        public void onDismiss() {
                            // popupWindow隐藏时恢复屏幕正常透明度
                            PopUtils.setBackgroundAlpha(MainActivity.this, 1.0f);
                        }
                    })
                    .create()
                    .showAsDropDown(mShowTop,0,10);
        }
    
        private void showRight() {
            View contentView = LayoutInflater.from(this).inflate(R.layout.popup_left_or_right,null);
            handleBottom(contentView);
            PopUtils.setBackgroundAlpha(MainActivity.this, 0.4f);
            mPopupWindow = new CustomPopWindow.PopupWindowBuilder(this)
                    .setView(contentView)
                    .size(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT)
                    .setFocusable(true)
                    .setOutsideTouchable(true)
                    .setAnimationStyle(R.style.AnimHorizontal)
                    .setOnDissmissListener(new PopupWindow.OnDismissListener() {
                        @Override
                        public void onDismiss() {
                            // popupWindow隐藏时恢复屏幕正常透明度
                            PopUtils.setBackgroundAlpha(MainActivity.this, 1.0f);
                        }
                    })
                    .create()
                    .showAsDropDown(mShowRignt,mShowRignt.getWidth(),-mShowRignt.getHeight());
        }
    
        private void showLeft() {
            View contentView = LayoutInflater.from(this).inflate(R.layout.popup_left_or_right,null);
            handleBottom(contentView);
            PopUtils.setBackgroundAlpha(MainActivity.this, 0.4f);
            mPopupWindow = new CustomPopWindow.PopupWindowBuilder(this)
                    .setView(contentView)
                    .size(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT)
                    .setFocusable(true)
                    .setOutsideTouchable(true)
                    .setAnimationStyle(R.style.AnimHorizontal)
                    .setOnDissmissListener(new PopupWindow.OnDismissListener() {
                        @Override
                        public void onDismiss() {
                            // popupWindow隐藏时恢复屏幕正常透明度
                            PopUtils.setBackgroundAlpha(MainActivity.this, 1.0f);
                        }
                    })
                    .create()
                    .showAsDropDown(mShowLeft,-mShowLeft.getWidth(),-mShowLeft.getHeight());
        }
    
        private void handleBottom(View contentView) {
            View.OnClickListener listener = new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mPopupWindow != null) {
                        mPopupWindow.dissmiss();
                    }
    
                    switch (v.getId()) {
                        case R.id.tv_like:
                            ToastUtils.showToast(MainActivity.this,"赞一个");
                            break;
    
                        case R.id.tv_hate:
                            ToastUtils.showToast(MainActivity.this,"踩一个");
                            break;
    
                        default:
                            break;
                    }
                }
            };
    
            //设置点击事件
            contentView.findViewById(R.id.tv_like).setOnClickListener(listener);
            contentView.findViewById(R.id.tv_hate).setOnClickListener(listener);
        }
    
    
        private void showSelectPhoto() {
            View contentView = LayoutInflater.from(this).inflate(R.layout.popup_up,null);
            handleLogic(contentView);
            PopUtils.setBackgroundAlpha(MainActivity.this, 0.4f);
            mPopupWindow = new CustomPopWindow.PopupWindowBuilder(this)
                    .setView(contentView)
                    .size(ViewGroup.LayoutParams.MATCH_PARENT,contentView.getMeasuredHeight())
                    .setFocusable(true)
                    .setOutsideTouchable(true)
                    .setAnimationStyle(R.style.AnimUp)
                    .setOnDissmissListener(new PopupWindow.OnDismissListener() {
                        @Override
                        public void onDismiss() {
                            // popupWindow隐藏时恢复屏幕正常透明度
                            PopUtils.setBackgroundAlpha(MainActivity.this, 1.0f);
                        }
                    })
                    .create()
                    .showAtLocation(mShowBottom,Gravity.BOTTOM,0,0);
        }
    
        private void handleLogic(View contentView) {
            View.OnClickListener listener = new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mPopupWindow != null) {
                        mPopupWindow.dissmiss();
                    }
    
                    switch (v.getId()) {
                        case R.id.btn_take_photo:
                            break;
    
                        case R.id.btn_select_photo:
                            break;
    
                        case R.id.btn_cancel:
                            break;
    
                        default:
                            break;
                    }
                }
            };
    
    
            //设置点击事件
            contentView.findViewById(R.id.btn_take_photo).setOnClickListener(listener);
            contentView.findViewById(R.id.btn_select_photo).setOnClickListener(listener);
            contentView.findViewById(R.id.btn_cancel).setOnClickListener(listener);
    
        }
    
    
    }
    

    相关文章

      网友评论

        本文标题:Android 小技巧之通用 PopupWindow

        本文链接:https://www.haomeiwen.com/subject/vcqtbktx.html