Android UI学习之鸿蒙&Android

Android 小技巧之通用 PopupWindow

2021-06-23  本文已影响0人  Kevin_小飞象
每日一图.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);

    }


}
上一篇下一篇

猜你喜欢

热点阅读