便捷的创建Dialog

便捷的创建Dialog

快速生成自定义弹窗
可链式
绑定activity/fragment生命周期

Dialog 实现
public abstract class BaseDialog<T, E> extends Dialog implements LifecycleObserver, LifecycleOwner {

    protected Context context;
    protected Builder builder;
    protected T confirmBtnClickListener;
    private Unbinder unbinder;
    protected E cancelBtnClickListener;
    private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

    private BaseDialog(@NonNull Context context, Builder builder, @StyleRes int style) {
        super(context, style);
        this.context = context;
        this.builder = builder;
        if (context instanceof LifecycleOwner) {
            ((LifecycleOwner) context).getLifecycle().addObserver(this);
        }
    }

    public BaseDialog(@NonNull Context context, Builder builder) {
        this(context, builder,R.style.DialogTheme_Base);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
        //提前设置Dialog的一些样式
        if (builder != null) {
            View inflate = LayoutInflater.from(context)
                    .inflate(CheckValueUtils.checkInteger(builder.layoutResId,
                            getClass().getSimpleName() + context.getString(R.string.s_no_layout_id)), null);
            unbinder = ButterKnife.bind(this, inflate);
            setContentView(inflate);
            Window dialogWindow = getWindow();
            if (dialogWindow != null) {
                dialogWindow.setGravity(builder.gravity);//设置dialog显示居中
                if (builder.animationStyle != null) {
                    dialogWindow.setWindowAnimations(builder.animationStyle);
                }
                WindowManager.LayoutParams attributes = dialogWindow.getAttributes();
                attributes.width = builder.with;
                attributes.height = builder.height;
                dialogWindow.setAttributes(attributes);
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    dialogWindow.setStatusBarColor(Color.TRANSPARENT);
                }
            }
            setCancelable(builder.cancelable);
            setCanceledOnTouchOutside(builder.canceledOnTouchOutside);
            initView(inflate);
            initData();
        }
    }

    public abstract void initView(View inflate);

    public abstract void initData();

    @NonNull
    @Override
    public Lifecycle getLifecycle() {
        return mLifecycleRegistry;
    }

    public static class Builder {
        private int gravity = Gravity.CENTER;
        private @StyleRes
        Integer animationStyle = null;

        private int with = WindowManager.LayoutParams.WRAP_CONTENT;
        private int height = WindowManager.LayoutParams.WRAP_CONTENT;
        private boolean canceledOnTouchOutside = true;
        private boolean cancelable = true;
        private int layoutResId;

        public Builder() {
        }

        public Builder(int with, int height) {
            this.with = with;
            this.height = height;
        }

        public Builder setGravity(int gravity) {
            this.gravity = gravity;
            return this;
        }

        public Builder setAnimation(@StyleRes Integer animationStyle) {
            this.animationStyle = animationStyle;
            return this;
        }

        public Builder setCancelable(boolean cancelable) {
            this.cancelable = cancelable;
            return this;
        }

        public Builder setCanceledOnTouchOutside(boolean canceledOnTouchOutside) {
            this.canceledOnTouchOutside = canceledOnTouchOutside;
            return this;
        }

        public Builder setWith(int with) {
            this.with = with;
            return this;
        }

        public Builder setHeight(int height) {
            this.height = height;
            return this;
        }

        public Builder setLayoutResId(@LayoutRes int layoutResId) {
            this.layoutResId = layoutResId;
            return this;
        }

        public void destroy() {
        }
    }

    public BaseDialog setOnConfirmBtnClickListener(T listener) {
        confirmBtnClickListener = listener;
        return this;
    }

    public BaseDialog setOnCancelBtnClickListener(E listener) {
        cancelBtnClickListener = listener;
        return this;
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)//和activity生命周期绑定后可用
    public void destroy() {
        dismiss();
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
        confirmBtnClickListener = null;
        cancelBtnClickListener = null;
        if (context instanceof LifecycleOwner) {
            ((LifecycleOwner) context).getLifecycle().removeObserver(this);
            context = null;
        }
        if (unbinder != null && unbinder != Unbinder.EMPTY) {
            unbinder.unbind();
            unbinder = null;
        }
        if (builder != null) {
            builder.destroy();
            builder = null;
        }
        mLifecycleRegistry = null;
    }

    @Override
    protected void onStart() {
        super.onStart();
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
    }

    @Override
    protected void onStop() {
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
        super.onStop();
    }
}

DialogTheme_Base
    <style name="DialogTheme_Base" parent="Theme.AppCompat.DayNight.Dialog.Alert">
        <item name="android:windowFrame">@null</item><!--边框-->
        <!-- 背景颜色及透明程度 -->
        <item name="android:windowBackground">@android:color/transparent</item>
        <!-- 是否半透明 -->
        <item name="android:windowIsTranslucent">false</item>
        <item name="android:background">@android:color/transparent</item>
        <!-- 是否没有标题 -->
        <item name="android:windowNoTitle">true</item>
        <!-- 是否浮现在activity之上 -->
        <item name="android:windowIsFloating">true</item>

        <item name="android:backgroundDimEnabled">true</item><!--模糊,背景透明是这个-->
        <!-- 设置背景模糊的透明度-->
        <item name="android:backgroundDimAmount">0.5</item>
    </style>
PopupWindow实现
public class BasePopupWindow extends PopupWindow implements LifecycleObserver, View.OnTouchListener, LifecycleOwner {

    private Builder builder;
    protected Context context;
    private Unbinder unbinder;
    private View contentView;
    private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    @CallSuper
    public void onDestroy() {
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
        dismiss();
        if (unbinder != null && unbinder != Unbinder.EMPTY) {
            unbinder.unbind();
        }
        unbinder = null;
        if (context instanceof LifecycleOwner) {
            ((LifecycleOwner) context).getLifecycle().removeObserver(this);
        }
        context = null;
        builder = null;
        mLifecycleRegistry = null;
    }

    protected BasePopupWindow(Builder builder, Context context) {
        this.builder = builder;
        this.context = context;
        if (context instanceof LifecycleOwner) {
            ((LifecycleOwner) context).getLifecycle().addObserver(this);
        }
        if (builder != null) {
            onCreate(builder);
            this.update();
        }
    }

    @CallSuper
    protected void onCreate(Builder builder) {
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
        if (builder.layoutRes != -1) {
            FrameLayout frameLayout = new FrameLayout(context);
            frameLayout.setLayoutParams(new FrameLayout.LayoutParams(builder.width, builder.height));
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            contentView = inflater.inflate(builder.layoutRes, frameLayout, false);
            unbinder = ButterKnife.bind(this, contentView);
            frameLayout.addView(contentView);
            this.setClippingEnabled(false);
            // 设置View
            this.setContentView(frameLayout);
            this.setWidth(builder.width);
            // 设置弹出窗体的高
            this.setHeight(builder.height);
            // 设置弹出窗体可点击
            this.setFocusable(builder.isFocusable);
            this.setOutsideTouchable(builder.isOutsideTouchable);
            //避免输入框被软键盘遮挡
            this.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
            // 刷新状态
            setBackgroundDrawable(new ColorDrawable(builder.isTransparent ? Color.TRANSPARENT : ResourcesUtils.getColor(R.color.translucent)));
            getContentView().measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
            if (builder.isOutsideTouchable) {
                getContentView().setOnTouchListener(this);
            }
        } else {
            throw new Resources.NotFoundException(ResourcesUtils.getString(R.string.s_no_layout_id));
        }
    }

    protected void refreshData(Builder builder) {
    }

    public void show() {
        if (!isShowing()) {
            Activity currentActivity = AppManager.getAppManager().getCurrentActivity();
            if (currentActivity != null && currentActivity.getWindow() != null) {
                showAtLocation(currentActivity.getWindow().getDecorView(), Gravity.CENTER, 0, 0);
            }
        }
        refreshData(builder);
    }

    @Override
    public void showAsDropDown(View anchor, int xoff, int yoff, int gravity) {
        super.showAsDropDown(anchor, xoff, yoff, gravity);
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
    }


    public void showAtLocation(View parent, int gravity, int x, int y) {
        super.showAtLocation(parent, gravity, x, y);
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP && ViewUtils.isOutsideTheView(contentView, event)) {
            dismiss();
        }
        return true;
    }

    @NonNull
    @Override
    public Lifecycle getLifecycle() {
        return mLifecycleRegistry;
    }

    @Override
    public void dismiss() {
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
        super.dismiss();
    }

    public abstract static class Builder {
        private @LayoutRes
        int layoutRes = -1;
        private int height = ViewGroup.LayoutParams.MATCH_PARENT;
        private int width = ViewGroup.LayoutParams.MATCH_PARENT;
        private boolean isTransparent = false;
        private boolean isFocusable = true;
        private boolean isOutsideTouchable = true;

        public Builder setLayoutRes(int layoutRes) {
            this.layoutRes = layoutRes;
            return this;
        }

        public Builder setHeight(int height) {
            this.height = height;
            return this;
        }

        public Builder setWidth(int width) {
            this.width = width;
            return this;
        }

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

        public Builder isTransparent(boolean isTransparent) {
            this.isTransparent = isTransparent;
            return this;
        }

        public Builder isOutsideTouchable(boolean isOutsideTouchable) {
            this.isOutsideTouchable = isOutsideTouchable;
            return this;
        }

        public abstract BasePopupWindow build(Context context);
    }
}

相关示例

仿支付宝密码输入弹窗:https://blog.csdn.net/TomCat0916/article/details/105776871

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值