PopupWindow使用和封装

PopupWindow工具类封装

我们这次来对PopupWindow来进行封装,使用Builder模式。

我们先来看我们要注意哪些因素要考虑:

  1. contentView ,这里有二种可能,一是用户只是传了R.layout.xxx进来,二是用户传了具体的View对象进来。
  2. PopupWindow的宽和高。 (可能需要传入Px值,可能是dp值,可能是R.dimen.xxx值,如果不传入,就默认为Wrap_Content,也就是会显示你传入的contentView的宽高)
  3. 是否需要显示动画,如果需要显示动画,那么具体的style参数
  4. focusable,touchable 的设置
  5. 是否设置点击外部让PopupWindow消失
  6. 设置里面的某个View的点击事件

PopuWindow在安卓7布局大小兼容问题的处理

在android7.0上,如果不主动约束PopuWindow的大小,

比如,设置布局大小为 MATCH_PARENT,那么PopuWindow会变得尽可能大,以至于 view下方无空间完全显示PopuWindow,而且view又无法向上滚动,此时PopuWindow会主动上移位置,直到可以显示完全。
解决办法:主动约束PopuWindow的内容大小,重写showAsDropDown方法:

所以初步我们可以写成这样:
 

public class CustomPopupWindow extends PopupWindow {

    private CustomPopupWindow(Builder builder) {
        super(builder.context);

        builder.view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
        setContentView(builder.view);
        setHeight(builder.height == 0?ViewGroup.LayoutParams.WRAP_CONTENT:builder.height);
        setWidth(builder.width == 0?ViewGroup.LayoutParams.WRAP_CONTENT:builder.width);
        if (builder.cancelTouchout) {
            setBackgroundDrawable(new ColorDrawable(0x00000000));//设置透明背景
            setOutsideTouchable(builder.cancelTouchout);//设置outside可点击
        }
        setFocusable(builder.isFocusable);
        setTouchable(builder.isTouchable);

        if(builder.animStyle != 0){
            setAnimationStyle(builder.animStyle);
        }
    }

    public static final class Builder {

        private Context context;
        private int height, width;
        private boolean cancelTouchout;
        private boolean isFocusable = true;
        private boolean isTouchable = true;
        private View view;
        private int animStyle;

        public Builder(Context context) {
            this.context = context;
        }

        public Builder view(int resView) {
            view = LayoutInflater.from(context).inflate(resView, null);
            return this;
        }

        public Builder view(View resVew){
            view = resVew;
            return this;
        }

        public Builder heightpx(int val) {
            height = val;
            return this;
        }

        public Builder widthpx(int val) {
            width = val;
            return this;
        }

        public Builder heightdp(int val) {
            height = dip2px(context, val);
            return this;
        }

        public Builder widthdp(int val) {
            width = dip2px(context, val);
            return this;
        }

        public Builder heightDimenRes(int dimenRes) {
            height = context.getResources().getDimensionPixelOffset(dimenRes);
            return this;
        }

        public Builder widthDimenRes(int dimenRes) {
            width = context.getResources().getDimensionPixelOffset(dimenRes);
            return this;
        }

        public Builder cancelTouchout(boolean val) {
            cancelTouchout = val;
            return this;
        }

        public Builder isFocusable(boolean val) {
            isFocusable = val;
            return this;
        }

        public Builder isTouchable(boolean val) {
            isTouchable = val;
            return this;
        }

        public Builder animStyle(int val){
            animStyle = val;
            return this;
        }

        public Builder addViewOnclick(int viewRes, View.OnClickListener listener) {
            view.findViewById(viewRes).setOnClickListener(listener);
            return this;
        }


        public CustomPopupWindow build() {

            return new CustomPopupWindow(this);
        }
    }
    
    @Override
    public int getWidth() {
        return getContentView().getMeasuredWidth();
    }

    /**
     * PopuWindow在安卓7布局大小兼容问题的处理
     *  在android7.0上,如果不主动约束PopuWindow的大小,比如,设置布局大小为 MATCH_PARENT,那么PopuWindow会变得尽可能大,
     *  以至于 view下方无空间完全显示PopuWindow,而且view又无法向上滚动,此时PopuWindow会主动上移位置,直到可以显示完全。
     * 解决办法:主动约束PopuWindow的内容大小,重写showAsDropDown方法:
     * @param anchor
     */
    @Override
    public void showAsDropDown(View anchor) {

        if (Build.VERSION.SDK_INT >= 24){
            Rect visibleFrame = new Rect();
            anchor.getGlobalVisibleRect(visibleFrame);
            int height = anchor.getResources().getDisplayMetrics().heightPixels - visibleFrame.bottom;
            setHeight(height);
        }
        super.showAsDropDown(anchor);
    }
    @Override
    public void showAsDropDown(View anchor, int xoff, int yoff) {
        if (Build.VERSION.SDK_INT >= 24) {
            Rect visibleFrame = new Rect();
            anchor.getGlobalVisibleRect(visibleFrame);
            int height = anchor.getResources().getDisplayMetrics().heightPixels - visibleFrame.bottom;
            setHeight(height);
        }
        super.showAsDropDown(anchor,xoff,yoff);
    }

    
    public static int dip2px(Context context, float dipValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dipValue * scale + 0.5f);
    }
}

参考:Android技能树 — PopupWindow小结

。。。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值