便捷的创建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