自定义Dialog原理

自定义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));
        }
    }

源码比较简单,上面仅仅说明思路,可自行实现适合自己的

你可能感兴趣的:(自定义Dialog原理)