封装一个通用的PopupWindow

移动开发 作者: 2024-08-22 20:50:01
上篇文章是关于建造者设计模式的,今天顺便封装一个通用的 PopupWindow 来实践一下, 同时也方便以后使用 PopupWindow,本文将从下面几个方面来介绍 PopupWindow 及其封装,
  1. 概述
  2. 常用方法
  3. 基本使用
  4. 封装 PopupWindow
  5. 使用封装后的PopupWindow
  6. 显示效果

概述

常用设置

 //构造方法
 public PopupWindow (Context context)  
 public PopupWindow(View contentView)  
 public PopupWindow(View contentView, int width, int height)  
 public PopupWindow(View contentView, int height, boolean focusable) 
 //设置View(必须)
 window.setContentView(contentView);
 //设置宽(必须)
 window.setWidth(WindowManager.LayoutParams.MATCH_PARENT);
 //设置高(必须)
 window.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
 //设置背景
 window.setBackgroundDrawable(new ColorDrawable(Color.GRAY));
 //设置PopupWindow之外的触摸事件
 window.setOutsideTouchable(true);
 //设置PopupWindow消失的监听器
 window.setOnDismissListener(this);
 //设置PopupWindow上的触摸事件
 window.setTouchable(true);
 //设置PopupWindow弹出动画
 window.setAnimationStyle(R.style.PopupWindowTranslateTheme);
//基于坐标,参数(当前窗口的某个 View,位置,起始坐标x,起始坐标y)
void showAtLocation (View parent, int gravity, int x, int y)
//基于某个View,参数(附着的View,x 方向的偏移量,y 方向的偏移量)
void showAsDropDown (View anchor, int xoff, int yoff, int gravity) 
void showAsDropDown (View anchor, int yoff)
void showAsDropDown (View anchor) 

基本使用

//创建PopupWindow
PopupWindow window = new PopupWindow(this);
//设置显示View
window.setContentView(contentView);
//设置宽高
window.setWidth(WindowManager.LayoutParams.MATCH_PARENT);
window.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
//设置背景
window.setBackgroundDrawable(new ColorDrawable(Color.GRAY));
//设置PopupWindow之外的触摸事件
window.setOutsideTouchable(true);
//设置PopupWindow消失的监听器
window.setOnDismissListener(new PopupWindow.OnDismissListener() {
    @Override
    public void onDismiss() {
        //监听PopupWindow的消失
    }
});
//设置PopupWindow上的触摸事件
window.setTouchable(true);
//设置PopupWindow弹出动画
window.setAnimationStyle(R.style.PopupWindowTranslateTheme);
window.showAtLocation(btnTarget, Gravity.BOTTOM | Gravity.CENTER, 0, 0);

封装 PopupWindow

//获取PopupWindow的宽高
mPopupWindow.getContentView().measure(
    View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
    View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
int popupWidth = mPopupWindow.getContentView().getMeasuredWidth();
int popupHeight = mPopupWindow.getContentView().getMeasuredHeight();
public Builder(Context context) {
    this.context = context;
    this.popupWindow = new PopupWindow(context);
    //默认PopupWindow响应触摸事件
    this.outsideTouchable = true;
    //默认响应触摸事件
    this.touchable = true;
    //默认背景透明
    this.backgroundDrawable = new ColorDrawable(Color.TRANSPARENT);
    //默认宽高为WRAP_CONTENT
    this.width  = WindowManager.LayoutParams.WRAP_CONTENT;
    this.height = WindowManager.LayoutParams.WRAP_CONTENT;
    //默认Gravity为Gravity.CENTER
    this.gravity = Gravity.CENTER;
    this.layoutId = -1;
    //默认偏移量为0
    this.offsetX = 0;
    this.offsetY = 0;
    //...
}
private void setPopupWindowConfig(MPopupWindow window) {
        if (contentView != null && layoutId != -1){
            throw new MException("setContentView and setLayoutId can't be used together.", "0");
        }else if (contentView == null && layoutId == -1){
            throw new MException("contentView or layoutId can't be null.", "1");
        }

        if (context == null) {
            throw new MException("context can't be null.", "2");
        } else {
            window.mContext = this.context;
        }

        window.mWidth  = this.width;
        window.mHeight = this.height;
        window.mView = this.contentView;
        window.mLayoutId = layoutId;
        window.mPopupWindow = this.popupWindow;
        window.mOutsideTouchable   = this.outsideTouchable;
        window.mBackgroundDrawable = this.backgroundDrawable;
        window.mOnDismissListener  = this.onDismissListener;
        window.mAnimationStyle = this.animationStyle;
        window.mTouchable = this.touchable;
        window.mOffsetX = this.offsetX;
        window.mOffsetY = this.offsetY;
        window.mGravity = this.gravity;
    }
}
public void showPopupWindow(View v, LocationType type) {
    if (mView!=null){
        mPopupWindow.setContentView(mView);
    }else if (mLayoutId != -1){
        View contentView = LayoutInflater.from(mContext).inflate(mLayoutId, null);
        mPopupWindow.setContentView(contentView);
    }
    mPopupWindow.setWidth(mWidth);
    mPopupWindow.setHeight(mHeight);
    mPopupWindow.setBackgroundDrawable(mBackgroundDrawable);
    mPopupWindow.setOutsideTouchable(mOutsideTouchable);
    mPopupWindow.setOnDismissListener(mOnDismissListener);
    mPopupWindow.setAnimationStyle(mAnimationStyle);
    mPopupWindow.setTouchable(mTouchable);
    //获取目标View的坐标
    int[] locations = new int[2];
    v.getLocationOnScreen(locations);
    int left = locations[0];
    int top  =  locations[1];
    //获取PopupWindow的宽高
    mPopupWindow.getContentView().measure(
            View.MeasureSpec.makeMeasureSpec(0,
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
    int popupWidth = mPopupWindow.getContentView().getMeasuredWidth();
    int popupHeight = mPopupWindow.getContentView().getMeasuredHeight();

    switch (type) {
        case TOP_LEFT:
            mPopupWindow.showAtLocation(v,Gravity.NO_GRAVITY,left - popupWidth + mOffsetX,top - popupHeight + mOffsetY);
            break;
        case TOP_CENTER:
            int offsetX = (v.getWidth() - popupWidth) / 2;
            mPopupWindow.showAtLocation(v,left + offsetX + mOffsetX,top - popupHeight + mOffsetY);
            break;
        case TOP_RIGHT:
            mPopupWindow.showAtLocation(v,left + v.getWidth() + mOffsetX,top - popupHeight + mOffsetY);
            break;

        case BOTTOM_LEFT:
            mPopupWindow.showAsDropDown(v, -popupWidth + mOffsetX,mOffsetY);
            break;
        case BOTTOM_CENTER:
            int offsetX1 = (v.getWidth() - popupWidth) / 2;
            mPopupWindow.showAsDropDown(v,offsetX1 + mOffsetX,mOffsetY);
            break;
        case BOTTOM_RIGHT:
            mPopupWindow.showAsDropDown(v, v.getWidth() + mOffsetX,mOffsetY);
            break;

        case LEFT_TOP:
            mPopupWindow.showAtLocation(v, Gravity.NO_GRAVITY, left - popupWidth + mOffsetX, top - popupHeight + mOffsetY);
            break;
        case LEFT_BOTTOM:
            mPopupWindow.showAtLocation(v, top + v.getHeight() + mOffsetY);
            break;
        case LEFT_CENTER:
            int offsetY = (v.getHeight() - popupHeight) / 2;
            mPopupWindow.showAtLocation(v,top + offsetY + mOffsetY);
            break;

        case RIGHT_TOP:
            mPopupWindow.showAtLocation(v, left + v.getWidth() + mOffsetX,top - popupHeight + mOffsetY);
            break;
        case RIGHT_BOTTOM:
            mPopupWindow.showAtLocation(v,top + v.getHeight() + mOffsetY);
            break;
        case RIGHT_CENTER:
            int offsetY1 = (v.getHeight() - popupHeight) / 2;
            mPopupWindow.showAtLocation(v,top + offsetY1 + mOffsetY);
            break;
        case FROM_BOTTOM:
            mPopupWindow.showAtLocation(v,mGravity,mOffsetX,mOffsetY);
            break;
    }
}

使用封装后的PopupWindow

private void showPopupWindow(MPopupWindow.LocationType type) {
    MPopupWindow popupWindow = new MPopupWindow
            .Builder(this)
            .setLayoutId(R.layout.popup_window_layout)
            .build();
    popupWindow.showPopupWindow(btnTarget, type);
}

显示效果:

原创声明
本站部分文章基于互联网的整理,我们会把真正“有用/优质”的文章整理提供给各位开发者。本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
本文链接:http://www.jiecseo.com/news/show_66866.html