自定义Dialog有很多种实现方式,有扩展Dialog自身的,基于PopUpWindow的,DialogFragment,自定义View, DecorView等等...
个人认为比较好的方案是直接在DecorView上面添加子View控件实现,下面是两个开源库的地址,实现原理均基于DecorView
https://github.com/orhanobut/dialogplus
https://github.com/Tapadoo/Alerter
获取Activity的DecorView
show
decorView = (ViewGroup) getActivityWeakReference().get().getWindow().getDecorView();
decorView.addView(getAlert());// getAlert是一个FrameLayout(子View)
hide
getAlert()被点击关闭按钮时触发
1.执行动画
2.监听动画结束时从decorView中remove掉自己
((ViewGroup) getParent()).removeView(Alert.this);
注意:在创建Dialog时候,如果前一个Dialog还没有手动关闭,记得判断下自行remove一次
如下
public static Alerter create(@NonNull final Activity activity) {
if (activity == null) {
throw new IllegalArgumentException("Activity cannot be null!");
}
final Alerter alerter = new Alerter();
//Clear Current Alert, if one is Active
Alerter.clearCurrent(activity);
alerter.setActivity(activity);
alerter.setAlert(new Alert(activity));
return alerter;
}
/**
* Cleans up the currently showing alert view, if one is present
*/
private static void clearCurrent(@NonNull final Activity activity) {
if (activity == null) {
return;
}
try {
final View alertView = activity.getWindow().getDecorView().findViewById(R.id.flAlertBackground);
//Check if the Alert is added to the Window
if (alertView == null || alertView.getWindowToken() == null) {
Log.d(Alerter.class.getClass().getSimpleName(), activity.getString(R.string.msg_no_alert_showing));
} else {
//Animate the Alpha
alertView.animate().alpha(0).withEndAction(new Runnable() {
@Override
public void run() {
//And remove the view for the parent layout
((ViewGroup) alertView.getParent()).removeView(alertView);
}
}).start();
Log.d(Alerter.class.getClass().getSimpleName(), activity.getString(R.string.msg_alert_cleared));
}
} catch (Exception ex) {
Log.e(Alerter.class.getClass().getSimpleName(), Log.getStackTraceString(ex));
}
}
源码比较简单,上面仅仅说明思路,可自行实现适合自己的