便捷的创建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);}@Overrideprotected 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@Overridepublic Lifecycle getLifecycle() {return mLifecycleRegistry;}public static class Builder {private int gravity = Gravity.CENTER;private @StyleResInteger 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;}@Overrideprotected void onStart() {super.onStart();mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);}@Overrideprotected 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)@CallSuperpublic 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();}}@CallSuperprotected 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);// 设置Viewthis.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);}@Overridepublic 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")@Overridepublic boolean onTouch(View v, MotionEvent event) {if (event.getAction() == MotionEvent.ACTION_UP && ViewUtils.isOutsideTheView(contentView, event)) {dismiss();}return true;}@NonNull@Overridepublic Lifecycle getLifecycle() {return mLifecycleRegistry;}@Overridepublic void dismiss() {mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);super.dismiss();}public abstract static class Builder {private @LayoutResint 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