public class ActivityStackManager {


    private static ActivityStackManager sInstance = new ActivityStackManager();
    private WeakReference<Activity> topAttachedActivityWeakRef;
    private static Stack<Activity> mActivityStack = new Stack<>();



    private ActivityStackManager() {

    }

    public static ActivityStackManager getInstance() {
        return sInstance;
    }


    /**
     * activity from oncreate callback is useable for dialog ,but not usable for popupwindow
     * @return
     */
    public Activity getTopActivity() {
        Activity currentActivity = null;
        if(mActivityStack.size()>0){
            currentActivity = mActivityStack.get(mActivityStack.size()-1);
        }
        /*Activity currentActivity = null;
        if (sCurrentActivityWeakRef != null) {
            currentActivity = sCurrentActivityWeakRef.get();
            if(currentActivity ==null){
                if(mActivityStack.size()>0){
                    currentActivity = mActivityStack.get(mActivityStack.size()-1);
                }
            }
            if(currentActivity !=null && currentActivity.isFinishing()){
                currentActivity = null;
            }
        }else {
            if(mActivityStack.size()>0){
                currentActivity = mActivityStack.get(mActivityStack.size()-1);
            }
            if(currentActivity !=null && currentActivity.isFinishing()){
                currentActivity = null;
            }
        }*/
        return currentActivity;
    }

    public Activity getTopActivity(Class activityExpected){
        Activity activity = getTopActivity();
        if(activity !=null && activity.getClass().equals(activityExpected)){
            return activity;
        }else {
            return null;
        }
    }

    public Activity getActivity(Class activityExpected){
        if (mActivityStack == null) {
            return null;
        }
        for (Activity activity1 : mActivityStack) {
            if (activity1.getClass().equals(activityExpected)) {
                return activity1;
            }
        }
        return null;
    }

    /**
     *
     * @param idxTop 从上往下的index,从1开始
     * @return
     */
    public boolean finishActivityByIdx(int idxTop){
        if(mActivityStack.isEmpty()){
            return false;
        }
        int index = mActivityStack.size() -idxTop;
       Activity activity =  mActivityStack.remove(index);
       if(activity !=null && !activity.isFinishing()){
           activity.finish();
           return true;
       }
       return true;
    }


    /**
     * 在基类activity 的 onAttachToWindow时调用
     * @param activity
     */
    public void setTopAttached(Activity activity) {
        topAttachedActivityWeakRef = new WeakReference<Activity>(activity);
    }

    /**
     * 在基类activity 的 onDetachToWindow时调用
     * @param activity
     */
    public void removeTopAttached(Activity activity){
        if(activity ==null){
            return;
        }
        if(topAttachedActivityWeakRef!=null){
            Activity activity1 =  topAttachedActivityWeakRef.get();
            if(activity.equals(activity1)){
                topAttachedActivityWeakRef = null;
            }

        }
    }

    /**
     * if return in not null,then it can be used for a popupwindow
     * @return
     */
    public Activity getTopAttached(){
        if(topAttachedActivityWeakRef!=null){
            Activity activity =  topAttachedActivityWeakRef.get();
            if(isUsable(activity)){
                return activity;
            }
        }
        return null;
    }

    public static boolean isUsable(Activity activity) {
        if(activity ==null){
            return false;
        }

        if(activity.isFinishing()){
            return false;
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            if (activity.isDestroyed()){
                return false;
            }
        }

        //是否attached
        /*if(activity.getWindowManager() ==null){
            return false;
        }
        if(!activity.getWindow().isActive()){
            return false;
        }*/

        return true;
    }


    /**
     * 返回栈大小
     *
     * @return 大小
     */
    public int size() {
        return mActivityStack.size();
    }

    /**
     * 添加Activity到堆栈
     */
    public void addActivity(Activity activity) {
        if (mActivityStack == null) {
            mActivityStack = new Stack<>();
        }
        if (activity != null) {
            mActivityStack.add(activity);
            Log.e("dialog","mActivityStack.size()--addActivity:"+activity.getClass().getSimpleName()+mActivityStack.size());
        }
    }

    /**
     * 移除activity
     */
    public void removeActivity(Activity activity) {
        mActivityStack.remove(activity);
        DialogsMaintainer.onDestory(activity);
        Log.e("dialog","mActivityStack.size()--removeActivity:"+activity.getClass().getSimpleName()+mActivityStack.size());
    }

    /**
     * 判断某个activity是否还存活
     *
     * @param cls
     * @return
     */
    public boolean isActivityAlive(Class<?> cls) {
        if (mActivityStack == null) {
            return false;
        }

        for (Activity activity1 : mActivityStack) {
            if (activity1.getClass().equals(cls)) {
                return true;
            }
        }

        return false;
    }

    /**
     * 结束指定的Activity
     */
    public void finishActivity(Activity activity) {
        if (mActivityStack == null) {
            return;
        }

        if (activity != null) {
            mActivityStack.remove(activity);
            activity.finish();
        }
    }

    /**
     * 结束指定类名的Activity
     */
    public void finishActivity(Class<?> cls) {
        if (mActivityStack == null) {
            return;
        }

        for (Activity activity : mActivityStack) {
            if (activity.getClass().equals(cls)) {
                finishActivity(activity);
            }
        }
    }
} public class StyledDialog {

    //android.support.v7.app.

    public static Context context;

    private static int singleChosen;



    //private static DialogInterface loadingDialog;//缓存加载中的dialog,便于以后可以不需要对象就让它消失
    //private static TextView tv_msg;
    private static long startTime;


    private static boolean isMiUi8 = false;//miui8用非activity的Context时,无法以TYPE_TOAST的形式弹出对话框.没有好的解决办法.....

    public static Handler getMainHandler() {
        if (mainHandler == null) {
            mainHandler = new Handler(Looper.getMainLooper());
        }
        return mainHandler;
    }

    private static Handler mainHandler;

    public static void init(Context context) {
        StyledDialog.context = context;
       /* String userAgent = System.getProperty("http.agent");
        if((!TextUtils.isEmpty(userAgent)) && userAgent.contains("MIUI") && userAgent.contains("V8")){
            isMiUi8 = true;
        }*/
        mainHandler = new Handler(Looper.getMainLooper());
        DefaultConfig.initBtnTxt(context);

    }




    /**
     * 一键让loading消失.
     */
    public static void dismissLoading(Activity activity) {
        DialogsMaintainer.dismissLoading(activity);
    }


    public static void dismiss(Dialog... dialogs) {
        if (dialogs != null && dialogs.length > 0) {
            for (DialogInterface dialog : dialogs) {
                try {
                    dialog.dismiss();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        }
    }


    public static ConfigBean buildProgress(CharSequence msg, boolean isHorizontal) {
        return DialogAssigner.getInstance().assignProgress(null, msg, isHorizontal);
    }

    public static void updateLoadingMsg(final String msg, final Dialog dialog) {
        if (dialog == null) {
            return;
        }
        if (!dialog.isShowing()) {
            return;
        }
        getMainHandler().post(new Runnable() {
            @Override
            public void run() {
                try {
                    View view = dialog.getWindow().getDecorView().findViewById(R.id.loading_msg);
                    if (view instanceof TextView) {
                        TextView textView = (TextView) view;
                        textView.setText(msg);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        });


    }

    /**
     * 可以在任何线程调用
     *
     * @param dialog       传入show方法返回的对象
     * @param progress
     * @param max
     * @param msg          如果是转圈圈,会将msg变成msg:78%的形式.如果是水平,msg不起作用
     * @param isHorizontal 是水平线状,还是转圈圈
     */
    public static void updateProgress(final Dialog dialog, final int progress, final int max, final CharSequence msg, final boolean isHorizontal) {

        getMainHandler().post(new Runnable() {
            @Override
            public void run() {
                if (dialog instanceof ProgressDialog && dialog.isShowing()) {
                    ProgressDialog progressDialog = (ProgressDialog) dialog;
                    if (isHorizontal) {
                        progressDialog.setProgress((int) progress);
                        progressDialog.setMax((int) max);
                    } else {
                        String pmsg = new StringBuilder(msg).append(":").append(progress * 100 / max).append("%").toString();
                        progressDialog.setMessage(pmsg);
                    }

                }
            }
        });


    }

    public static ConfigBean buildLoading(CharSequence msg) {
        return DialogAssigner.getInstance().assignLoading(null, msg, true, false);
    }

    public static ConfigBean buildLoading() {
        return DialogAssigner.getInstance().assignLoading(null, DefaultConfig.loadingTxt, true, false);
    }

    public static ConfigBean buildMdLoading() {
        return DialogAssigner.getInstance().assignMdLoading(null, DefaultConfig.loadingTxt, true, false);
    }

    public static ConfigBean buildMdLoading(CharSequence msg) {
        return DialogAssigner.getInstance().assignMdLoading(null, msg, true, false);
    }


    public static ConfigBean buildMdAlert(CharSequence title, CharSequence msg, MyDialogListener listener) {
        return DialogAssigner.getInstance().assignMdAlert(null, title, msg, listener);
    }


    public static ConfigBean buildMdSingleChoose(CharSequence title, int defaultChosen, CharSequence[] words, MyItemDialogListener listener) {
        return DialogAssigner.getInstance().assignMdSingleChoose(null, title, defaultChosen, words, listener);
    }

    @Deprecated
    public static ConfigBean buildMdMultiChoose(CharSequence title, CharSequence[] words, boolean[] checkedItems, MyDialogListener btnListener) {
        return DialogAssigner.getInstance().assignMdMultiChoose(null, title, words, checkedItems, btnListener);
    }

    public static ConfigBean buildMdMultiChoose(CharSequence title, CharSequence[] words, List<Integer> selectedIndexs, MyDialogListener btnListener) {
        return DialogAssigner.getInstance().assignMdMultiChoose(null, title, words, selectedIndexs, btnListener);
    }


    public static ConfigBean buildIosAlert(CharSequence title, CharSequence msg, MyDialogListener listener) {
        return DialogAssigner.getInstance().assignIosAlert(null, title, msg, listener);
    }


    public static ConfigBean buildIosAlertVertical(CharSequence title, CharSequence msg, MyDialogListener listener) {
        return DialogAssigner.getInstance().assignIosAlertVertical(null, title, msg, listener);
    }


    public static ConfigBean buildIosSingleChoose(List<? extends CharSequence> words, MyItemDialogListener listener) {
        return DialogAssigner.getInstance().assignIosSingleChoose(null, words, listener);
    }


    public static ConfigBean buildBottomItemDialog(List<? extends CharSequence> words, CharSequence bottomTxt, MyItemDialogListener listener) {
        return DialogAssigner.getInstance().assignBottomItemDialog(null, words, bottomTxt, listener);
    }


    public static ConfigBean buildNormalInput(CharSequence title, CharSequence hint1, CharSequence hint2,
                                              CharSequence inputText1, CharSequence inputText2, MyDialogListener listener) {
        return DialogAssigner.getInstance().assignNormalInput(null, title, hint1, hint2, inputText1, inputText2, listener);
    }

    public static ConfigBean buildMdInput(CharSequence title, CharSequence hint1, CharSequence hint2,
                                          CharSequence inputText1, CharSequence inputText2, MyDialogListener listener) {
        return DialogAssigner.getInstance().buildMdInput(title, hint1, hint2, inputText1, inputText2, listener);

    }


    /**
     * 将view塞到meterial alert dialog 中, 可以沿用其title和button的样式和更改方法,该view作为content显示
     *
     * @param customViewHolder
     * @return
     */
    public static ConfigBean buildCustomInMd(SuperLvHolder customViewHolder, MyDialogListener listener) {
        return DialogAssigner.getInstance().buildCustomInMd(customViewHolder, listener);
    }


    /**
     * 将view塞到ios样式的 dialog 中, 可以沿用其title和button的样式和更改方法,该view作为content显示
     *
     * @param customViewHolder
     * @return
     */
    public static ConfigBean buildCustomInIos(SuperLvHolder customViewHolder, MyDialogListener listener) {
        return DialogAssigner.getInstance().buildCustomInIos(customViewHolder, listener);
    }

    /**
     * use buildCustom( SuperLvHolder viewHolder)  instead
     * 建议使用SuperLvHolder 对自定义view进行包装,如果有输入框,则实现控制软键盘的显示和隐藏方法,框架会在合适的时间帮你显示和隐藏
     *
     * @param contentView
     * @param gravity
     * @return
     */
    @Deprecated
    public static ConfigBean buildCustom(View contentView, int gravity) {
        return DialogAssigner.getInstance().assignCustom(null, contentView, gravity);
    }

    /**
     * 带x的view,x的位置可以配置
     * @param contentView
     * @return
     */
    public static ConfigBean buildCustomAsAdStyle(View contentView,  int xGravity) {
        ConfigBean configBean =  DialogAssigner.getInstance().assignCustom(null, contentView, Gravity.CENTER);
        configBean.asAdXStyle = true;
        configBean.xGravity = xGravity;
        configBean.useTheShadowBg = false;
        return configBean;
    }

    public static ConfigBean buildAlertAsAdStyle(String title,String msg,  int xGravity) {
        IosAlertDialogHolder dialogHolder = new IosAlertDialogHolder(ActivityStackManager.getInstance().getTopActivity());
        dialogHolder.showOnlyTitleAndMsg(title,msg);
        ConfigBean configBean =  DialogAssigner.getInstance().assignCustom(null, dialogHolder.rootView, Gravity.CENTER);
        configBean.hint1 = "";
        configBean.hint1 = "";
        configBean.text1 = "";
        configBean.text2 = "";
        configBean.text3 = "";
       // dialogHolder.assingDatasAndEvents(ActivityStackManager.getInstance().getTopActivity(),configBean);
        configBean.asAdXStyle = true;
        configBean.xGravity = xGravity;
        configBean.useTheShadowBg = false;
        return configBean;
    }


    public static ConfigBean buildCustom(SuperLvHolder viewHolder) {
        return DialogAssigner.getInstance().assignCustom(null, viewHolder);
    }


    public static ConfigBean buildCustomBottomSheet(View contentView) {
        return DialogAssigner.getInstance().assignCustomBottomSheet(null, contentView);
    }

    public static ConfigBean buildBottomSheetLv(CharSequence title, List datas, CharSequence bottomTxt, MyItemDialogListener listener) {
        return DialogAssigner.getInstance().assignBottomSheetLv(null, title, datas, bottomTxt, listener);
    }

    public static ConfigBean buildBottomSheetGv(CharSequence title, List datas, CharSequence bottomTxt, int columnsNum, MyItemDialogListener listener) {
        return DialogAssigner.getInstance().assignBottomSheetGv(null, title, datas, bottomTxt, columnsNum, listener);
    }

} public class Tool {

    public static void dismiss(ConfigBean bean,boolean isAfterResult){

        if(isAfterResult && !bean.dismissAfterResultCallback){
            return;
        }

        //先隐藏keyboard
        hideKeyBorad(bean);
        if(bean.showAsActivity){
            Activity activity = ActivityStackManager.getInstance().getTopActivity(DialogUtil_DialogActivity.class);
            if(activity!=null){
                activity.finish();
            }
            return;
        }
        if(bean.showAsFragment){
            if(bean.mDialogFragment !=null ){
                bean.mDialogFragment.dismiss();
                return;
            }
        }
        if(bean.dialog!=null){
            bean.dialog.dismiss();
        }
        if(bean.alertDialog !=null){
            bean.alertDialog.dismiss();
        }
    }

    public static void dismiss(ConfigBean bean){
        dismiss(bean,false);
    }


    public static Handler getMainHandler() {
        if(mainHandler ==null){
            mainHandler = new Handler(Looper.getMainLooper());
        }
        return mainHandler;
    }

    private static Handler mainHandler;

    /**
     * 解决badtoken问题,一劳永逸
     * @param dialog
     */
    public static void showDialog(final Dialog dialog, final ConfigBean bean) {
        StyledDialog.getMainHandler().post(new Runnable() {
            @Override
            public void run() {
                try {
                    dialog.show();
                    adjustWindow(dialog,bean);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        });
    }


    public static void setListener(final Dialog dialog, final ConfigBean bean) {
        if(dialog ==null){
            return;
        }

        dialog.setOnShowListener(new DialogInterface.OnShowListener() {
            @Override
            public void onShow(DialogInterface dialog0) {
                if (bean.alertDialog!= null){
                    setMdBtnStytle(bean);
                    setTitleMessageStyle(bean.alertDialog,bean);
                }
                bean.listener.onShow();
                DialogsMaintainer.addWhenShow(bean.context,dialog);
                if (bean.type == DefaultConfig.TYPE_IOS_LOADING || bean.type == DefaultConfig.TYPE_MD_LOADING) {
                    DialogsMaintainer.addLoadingDialog(bean.context,dialog);
                }

                 /*dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE |
                     WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
                Tool.showSoftKeyBoardDelayed(bean.needSoftKeyboard,bean.viewHolder);
                Tool.showSoftKeyBoardDelayed(bean.needSoftKeyboard,bean.customContentHolder);*/
            }
        });

        dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog0) {
                if(bean.type == DefaultConfig.TYPE_IOS_INPUT){
                    IosAlertDialogHolder iosAlertDialogHolder = (IosAlertDialogHolder) bean.viewHolder;
                    if(iosAlertDialogHolder!=null){
                        iosAlertDialogHolder.hideKeyBoard();
                    }
                }
                if(bean.listener!=null) {
                    bean.listener.onCancle();
                }
                /*DialogsMaintainer.removeWhenDismiss(dialog);
                if (bean.type == DefaultConfig.TYPE_IOS_LOADING || bean.type == DefaultConfig.TYPE_MD_LOADING) {
                    DialogsMaintainer.dismissLoading(dialog);

                }*/
            }
        });

        dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
            @Override
            public void onDismiss(DialogInterface dialog0) {
                if(bean.listener !=null){
                    bean.listener.onDismiss();
                }
                DialogsMaintainer.removeWhenDismiss(dialog);
                if (bean.type == DefaultConfig.TYPE_IOS_LOADING || bean.type == DefaultConfig.TYPE_MD_LOADING) {
                    DialogsMaintainer.dismissLoading(dialog);

                }
            }
        });


    }

    private static void setTitleMessageStyle(final Dialog dialog,ConfigBean bean) {

        try {
            Field mAlert = AlertDialog.class.getDeclaredField("mAlert");
            mAlert.setAccessible(true);
            Object mAlertController = mAlert.get(dialog);


            Field mMessage = mAlertController.getClass().getDeclaredField("mMessageView");
            mMessage.setAccessible(true);
            TextView tvMessage = (TextView) mMessage.get(mAlertController);
            if(bean.msgTxtColor !=0){
                tvMessage.setTextColor(getColor(bean.context,bean.msgTxtColor));
            }
            if(bean.msgTxtSize !=0){
                tvMessage.setTextSize(bean.msgTxtSize);
            }

            Field titleView = mAlertController.getClass().getDeclaredField("mTitleView");
            titleView.setAccessible(true);
            TextView tvTitle = (TextView) titleView.get(mAlertController);
            if(bean.titleTxtColor !=0){
                tvTitle.setTextColor(getColor(bean.context,bean.titleTxtColor));
            }
            if(bean.titleTxtSize !=0){
                tvTitle.setTextSize(bean.titleTxtSize);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private static void adjustWindow(final Dialog dialog, final ConfigBean bean) {
        dialog.getWindow().getDecorView().getViewTreeObserver()
                .addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                    @Override
                    public void onGlobalLayout() {
                        setBottomSheetDialogPeekHeight(bean);
                        adjustWH(dialog,bean);
                        dialog.getWindow().getDecorView().getViewTreeObserver().removeGlobalOnLayoutListener(this);



                    }
                });
    }

    public static void setWindowAnimation(Window window, ConfigBean bean) {
        int gravity = bean.gravity;
        if(gravity == Gravity.BOTTOM || gravity == (Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL)){
            window.setWindowAnimations(R.style.ani_bottom);
        }else if(gravity == Gravity.CENTER){
            //window.setWindowAnimations(R.style.dialog_center);
        }
    }



    public static void runOnUIThread(Runnable runnable){
        if(mainHandler ==null){
            mainHandler = new Handler(Looper.getMainLooper());
        }
        mainHandler.post(runnable);
    }

    public static void runOnUIThreadDelayed(Runnable runnable){
        if(mainHandler ==null){
            mainHandler = new Handler(Looper.getMainLooper());
        }
        mainHandler.postDelayed(runnable,500);
    }

    public static void showSoftKeyBoardDelayed(boolean sholudShouldKeyBoard,final SuperLvHolder holder){
        if(!sholudShouldKeyBoard){
            return;
        }
        if(holder ==null){
            return;
        }
        /*if(mainHandler ==null){
            mainHandler = new Handler(Looper.getMainLooper());
        }
        mainHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                holder.showKeyBoard();
            }
        }, 0);*/
        holder.showKeyBoard();
    }


    /**
     * 必须在show之后,button才不会返回null
     * @param bean
     */
    public static void setMdBtnStytle(final ConfigBean bean){
        Button btnPositive =
                bean.alertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
        Button btnNegative =
                bean.alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE);
        Button btnNatural =
                bean.alertDialog.getButton(DialogInterface.BUTTON_NEUTRAL);

        if(btnPositive !=null){
            btnPositive.setAllCaps(false);
            if(!TextUtils.isEmpty(bean.text1)){
                btnPositive.setText(bean.text1);
            }
            if (bean.btn1Color > 0){
                btnPositive.setTextColor(getColor(bean.context,bean.btn1Color));
            }

            if(bean.btnTxtSize >0){
                btnPositive.setTextSize(bean.btnTxtSize);
            }
            btnPositive.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(bean.type == DefaultConfig.TYPE_MD_INPUT){
                        MdInputHolder holder = (MdInputHolder) bean.viewHolder;
                        boolean isvalid = bean.listener.onInputValid(holder.getTxt1(),holder.getTxt2(),holder.getEt1(),holder.getEt2());
                        if(!isvalid){
                            return;
                        }
                        bean.listener.onGetInput(holder.getTxt1(),holder.getTxt2());
                    }else if(bean.type == DefaultConfig.TYPE_MD_SINGLE_CHOOSE){

                    }else if(bean.type == DefaultConfig.TYPE_MD_MULTI_CHOOSE){
                        bean.listener.onGetChoose(bean.checkedItems);
                        List<Integer> selectedIndex = new ArrayList<Integer>();
                        List<CharSequence> selectedStrs = new ArrayList<CharSequence>();
                        for(int j=0;j<bean.checkedItems.length;j++){
                            if(bean.checkedItems[j]){
                                selectedIndex.add(j);
                                selectedStrs.add(bean.wordsMd[j]);
                            }
                        }
                        bean.listener.onChoosen(selectedIndex,selectedStrs,bean.checkedItems);
                    }
                    bean.listener.onFirst();
                    dismiss(bean,true);
                }
            });
        }
        if(btnNegative !=null){
            btnNegative.setAllCaps(false);
            if(!TextUtils.isEmpty(bean.text2)){
                btnNegative.setText(bean.text2);
            }
            if (bean.btn2Color > 0 ){
                if(bean.btn2Color == DefaultConfig.iosBtnColor ){
                    btnNegative.setTextColor(getColor(bean.context,R.color.dialogutil_text_gray));
                }else {
                    btnNegative.setTextColor(getColor(bean.context,bean.btn2Color));
                }
            }


            if(bean.btnTxtSize >0){
                btnNegative.setTextSize(bean.btnTxtSize);
            }
        }

        if(btnNatural !=null){
            btnNatural.setAllCaps(false);
            if(!TextUtils.isEmpty(bean.text3)){
                btnNatural.setText(bean.text3);
            }
            if (bean.btn3Color > 0){
                btnNatural.setTextColor(getColor(ActivityStackManager.getInstance().getTopActivity(),bean.btn3Color));
            }

            if(bean.btnTxtSize >0){
                btnNatural.setTextSize(bean.btnTxtSize);
            }
        }


    }

    public static ConfigBean fixContext(ConfigBean bean){
        Activity activity1 = null;

        if(!(bean.context instanceof  Activity)){
            Activity activity = ActivityStackManager.getInstance().getTopActivity();
            if(isUsable(activity)){
                activity1 = activity;

            }
        }else {
            Activity activity = (Activity) bean.context;
           if(isUsable(activity)){
               activity1 = activity;
           }
        }
        if(activity1 !=null){
            bean.context = activity1;
        }else {
            bean.context = StyledDialog.context;
        }

        Log.e("tool","fixContext:"+bean.context);
        return bean;
    }

    public static boolean isUsable(Activity activity) {
        if(activity ==null){
            return false;
        }

        if(activity.isFinishing()){
            return false;
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            if (activity.isDestroyed()){
                return false;
            }
        }

        //是否attached
        /*if(activity.getWindowManager() ==null){
            return false;
        }
        if(!activity.getWindow().isActive()){
            return false;
        }*/

        return true;
    }


    /**
     * ViewRootImpl.checkThread:只有创建View层次结构的线程才能修改View
     * 如何保证new Dialog在UI线程执行?或者说,保证构建dialog view的线程和dismiss在同一线程?
     * 查看源码知道,dismiss回强制在UI线程,所以,构建dialogview的线程也必须是UI线程.
     * 什么时候构建dialog的viewroot?
     * 普通dialog: new Dialog()方法中: Window w = new PhoneWindow(mContext)
     * alertdialog: dialogbuilder.build()方法中
     *
     * @param bean
     * @return
     */
    public static ConfigBean newCustomDialog(ConfigBean bean){
        Dialog dialog = new Dialog(bean.context);
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        bean.dialog = dialog;
        return bean;
    }

    public static ConfigBean setCancelable(ConfigBean bean){

        if (bean.alertDialog != null){
            bean.alertDialog.setCancelable(bean.cancelable);
            bean.alertDialog.setCanceledOnTouchOutside(bean.outsideTouchable);
           // bean.alertDialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
        }else if (bean.dialog != null){
            bean.dialog.setCancelable(bean.cancelable);
            bean.dialog.setCanceledOnTouchOutside(bean.outsideTouchable);
          //  bean.dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
        }
        return bean;
    }







    public static void adjustStyle(final ConfigBean bean) {
        /*if (bean.alertDialog!= null){
            //setMdBtnStytle(bean);
            //setListItemsStyle(bean);
           // adjustStyle(bean.context,bean.dialog,bean.viewHeight,bean);

        }else {
            adjustWH(bean.context,bean.dialog,bean.viewHeight,bean);
        }*/

        setBg(bean);
       // bean.isTransparentBehind = true;
        setDim(bean);
        Dialog dialog = bean.dialog ==null ? bean.alertDialog : bean.dialog;
        Window window = dialog.getWindow();
        window.setGravity(bean.gravity);
        if(bean.context instanceof Activity){
            //setHomeKeyListener(window,bean);
        }else {
            window.setType(WindowManager.LayoutParams.TYPE_TOAST);
            WindowManager.LayoutParams params = window.getAttributes();
            if(params==null){
                params = new WindowManager.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            }
            params.format = PixelFormat.RGBA_8888;
            params.flags =
               // WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL  |
                WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE  |
                WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH |
                WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
            params.dimAmount = 0.2f;
            //params.alpha = 0.5f;//the alpha of window

            window.setAttributes(params);

            // back key pressed
            window.getDecorView().setOnKeyListener(new View.OnKeyListener() {
                @Override
                public boolean onKey(View v, int keyCode, KeyEvent event) {
                    if (keyCode == KeyEvent.KEYCODE_BACK || event.getKeyCode() == KeyEvent.KEYCODE_SETTINGS) {
                        StyledDialog.dismiss(bean.alertDialog,bean.dialog);
                        return true;
                    }
                    return false;
                }
            });
            // home key pressed
            setHomeKeyListener(window,bean);

            //todo outside not touchable

            //todo dim behind
            window.setDimAmount(0.2f);

        }

    }

    private  static void setHomeKeyListener(final Window window, final ConfigBean bean){
        //在创建View时注册Receiver
        IntentFilter homeFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
        bean.homeKeyReceiver = new BroadcastReceiver() {
            final String SYSTEM_DIALOG_REASON_KEY = "reason";

            final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";

            @Override
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
                if (action.equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
                    String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY);
                    if (reason != null && reason.equals(SYSTEM_DIALOG_REASON_HOME_KEY)) {
                        // 处理自己的逻辑
                        if(bean.type == DefaultConfig.TYPE_IOS_INPUT){
                            hideKeyBoard(window);
                        }
                        if(!(bean.context instanceof Activity)){
                           Tool.dismiss(bean);
                        }

                        context.unregisterReceiver(this);
                    }
                }
            }
        };
        bean.context.registerReceiver(bean.homeKeyReceiver, homeFilter);
    }



    private static void setDim(ConfigBean bean) {
        if(bean.type == DefaultConfig.TYPE_IOS_LOADING){//转菊花,则让背景透明
            bean.isTransparentBehind = true;
        }
        if (bean.alertDialog!= null){
           if(bean.isTransparentBehind){
               bean.alertDialog.getWindow().setDimAmount(0);
           }
        }else {
            if(bean.isTransparentBehind){
                bean.dialog.getWindow().setDimAmount(0);
            }
        }
    }

    /**
     * set background of dialog window
     * @param bean
     */
    private static void setBg(ConfigBean bean) {
        //no need to modify the background
        if((bean.type == DefaultConfig.TYPE_BOTTOM_SHEET_GRID && bean.hasBehaviour)
            || bean.type == DefaultConfig.TYPE_BOTTOM_SHEET_LIST
            || bean.type == DefaultConfig.TYPE_BOTTOM_SHEET_CUSTOM
            || bean.type == DefaultConfig.TYPE_PROGRESS){
            // No need to set backgroud
            return;

        }


        if (bean.alertDialog!= null){

            if(bean.useTheShadowBg){
                bean.alertDialog.getWindow().setBackgroundDrawableResource(R.drawable.shadow);
            }else {
                if(bean.bgRes>0)
                     bean.alertDialog.getWindow().setBackgroundDrawableResource(bean.bgRes);
                else {
                    bean.alertDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
                }

            }
        }else {
             if(bean.type == DefaultConfig.TYPE_IOS_LOADING  ){//转菊花时,背景透明
                bean.dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
            }else if((bean.type == DefaultConfig.TYPE_BOTTOM_SHEET_GRID && !bean.hasBehaviour)){
                 bean.dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.WHITE));
             }else {
                if(bean.useTheShadowBg){
                    bean.dialog.getWindow().setBackgroundDrawableResource(R.drawable.shadow);
                }else {
                    if(bean.bgRes>0)
                        bean.dialog.getWindow().setBackgroundDrawableResource(bean.bgRes);
                    else {
                        bean.dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
                    }
                }
            }

        }


    }







    public static void adjustWH( Dialog dialog,  ConfigBean bean ) {
        if (dialog == null){
            return;
        }

        Window window = dialog.getWindow();
        View rootView = window.getDecorView();
        //window.setWindowAnimations(R.style.dialog_center);
        WindowManager.LayoutParams wl = window.getAttributes();

        int width = window.getWindowManager().getDefaultDisplay().getWidth();
        int height = window.getWindowManager().getDefaultDisplay().getHeight();
        int measuredHeight = rootView.getMeasuredHeight();
        int measuredWidth = rootView.getMeasuredWidth();

        float widthRatio = 0.85f;
        float heightRatio = 0f;
        if(bean.type ==DefaultConfig.TYPE_IOS_BOTTOM){
            widthRatio = 0.95f;
        }else if(bean.type ==DefaultConfig.TYPE_IOS_CENTER_LIST){
            widthRatio = 0.9f;
        }
        if(width > height){//宽屏
            widthRatio = 0.5f;
        }

        //set ratio as user has set
        if(bean.forceWidthPercent >0 && bean.forceWidthPercent <=1.0f){
            widthRatio = bean.forceWidthPercent;
        }
        if(measuredHeight > bean.maxHeightPercent * height){
            heightRatio = bean.maxHeightPercent;
        }
        if(bean.forceHeightPercent >0 && bean.forceHeightPercent <=1.0f){
            heightRatio = bean.forceHeightPercent;
        }

        if(istheTypeOfNotAdjust(bean)){
            /*wl.width = ViewGroup.LayoutParams.WRAP_CONTENT;
            wl.height = ViewGroup.LayoutParams.WRAP_CONTENT;*/

        }else {
           // rootView.setPadding(0,30,0,30);
            wl.width = (int) (width * widthRatio);//stretch when the content is not enough,margin when the content is full fill the screen
            //if (measuredHeight > height* heightRatio){//only work when the content is full fill the screen
            if(heightRatio>0){
                wl.height = (int) (height* heightRatio);
            }

            if(bean.type == DefaultConfig.TYPE_BOTTOM_SHEET_GRID && !bean.hasBehaviour){
                wl.height =measuredHeight;
            }

           // }
        }

        dialog.onWindowAttributesChanged(wl);
    }

    public static boolean istheTypeOfNotAdjust(ConfigBean bean) {
        switch (bean.type){
            case DefaultConfig.TYPE_IOS_LOADING:
            case DefaultConfig.TYPE_PROGRESS:
            case DefaultConfig.TYPE_BOTTOM_SHEET_CUSTOM:
            case DefaultConfig.TYPE_BOTTOM_SHEET_LIST:
           // case DefaultConfig.TYPE_CUSTOM_VIEW:
                return true;
           case DefaultConfig.TYPE_BOTTOM_SHEET_GRID:
               return bean.hasBehaviour;
            default:
                return false;
        }
    }

    private static boolean isCustomType(ConfigBean bean) {
        switch (bean.type){
            case DefaultConfig.TYPE_IOS_HORIZONTAL:
            case DefaultConfig.TYPE_IOS_VERTICAL:
            case DefaultConfig.TYPE_IOS_BOTTOM:
            case DefaultConfig.TYPE_IOS_CENTER_LIST:
            case DefaultConfig.TYPE_IOS_INPUT:
            case DefaultConfig.TYPE_CUSTOM_VIEW:
            case DefaultConfig.TYPE_MD_LOADING:
            case DefaultConfig.TYPE_MD_ALERT:
            case DefaultConfig.TYPE_MD_MULTI_CHOOSE:
            case DefaultConfig.TYPE_MD_SINGLE_CHOOSE:
            return true;
            default:
                return false;
        }
    }


    public static void measureView(View child) {
        ViewGroup.LayoutParams p = child.getLayoutParams();
        if (p == null) {
            p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT
                    ,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
        }
        int lpHeight = p.height;
        int lpWidth = p.width;
        int childHeightSpec;
        int childWidthSpec;
        if (lpHeight > 0) {   //如果Height是一个定值，那么我们测量的时候就使用这个定值
            childHeightSpec = View.MeasureSpec.makeMeasureSpec(lpHeight,
                    View.MeasureSpec.EXACTLY);
        } else {  // 否则，我们将mode设置为不指定，size设置为0
            childHeightSpec = View.MeasureSpec.makeMeasureSpec(0,
                    View.MeasureSpec.UNSPECIFIED);
        }
        if (lpWidth > 0) {
            childWidthSpec= View.MeasureSpec.makeMeasureSpec(lpHeight,
                    View.MeasureSpec.EXACTLY);
        } else {
            childWidthSpec= View.MeasureSpec.makeMeasureSpec(0,
                    View.MeasureSpec.UNSPECIFIED);
        }
        child.measure(childWidthSpec, childHeightSpec);
    }

    /**
     *
     * @param root
     * @param id  height为0,weight为1的scrollview包裹的view的id,如果没有,传0或负数即可
     * @return
     */
    public static int mesureHeight(View root, int id) {
        measureView(root);
        int height = root.getMeasuredHeight();
        int heightExtra = 0;
        if (id > 0){
            View view = root.findViewById(id);
            if (view != null){
                measureView(view);
                heightExtra = view.getMeasuredHeight();
            }

        }
        return height + heightExtra;
    }

    public static int mesureHeight(View root, View... subViews) {
        measureView(root);
        int height = root.getMeasuredHeight();
        int heightExtra = 0;
        if (subViews != null && subViews.length>0){
            for (View view : subViews){
                if(view.getVisibility() == View.VISIBLE){//确保设置了gone的view不再出现
                    measureView(view);
                    heightExtra += view.getMeasuredHeight();
                }

            }

        }

        return height + heightExtra;
    }

    public static int getColor(Context context,int colorRes){
        if (context ==null){
            context = StyledDialog.context;
        }
        try {
            int color =  context.getResources().getColor(colorRes);
            return color;
        }catch (Exception e){
            e.printStackTrace();
            return Color.TRANSPARENT;
        }


    }




    public static void handleScrollInBottomSheetDialog(final AdapterView listView){
        listView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (!listView.canScrollVertically(-1)) {      //canScrollVertically(-1)的值表示是否能向下滚动，false表示已经滚动到顶部
                    listView.requestDisallowInterceptTouchEvent(false);
                }else{
                    listView.requestDisallowInterceptTouchEvent(true);
                }
                return false;
            }
        });


    }


    /**
     * 设置BottomSheetDialog的初始最大高度,解决dismiss后无法再show的问题
     * @param bean
     */
    public static void setBottomSheetDialogPeekHeight(final ConfigBean bean){
        if(bean.hasBehaviour && bean.dialog instanceof BottomSheetDialog){
            View view = bean.dialog.getWindow().findViewById(android.support.design.R.id.design_bottom_sheet);

            if(view ==null){
                return;
            }

            final BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(view);
            bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
                @Override
                public void onStateChanged(@NonNull View bottomSheet, int newState) {
                    if (newState == BottomSheetBehavior.STATE_HIDDEN) {
                        Tool.dismiss(bean);
                        bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
                    }
                }
                @Override
                public void onSlide(@NonNull View bottomSheet, float slideOffset) {
                }
            });

            if(bean.bottomSheetDialogMaxHeightPercent >0f && bean.bottomSheetDialogMaxHeightPercent <1f){
                int peekHeight = (int) (bean.bottomSheetDialogMaxHeightPercent * ScreenUtil.getScreenHeight());
                bottomSheetBehavior.setPeekHeight(peekHeight);
            }
        }
    }

    public static void showKeyBoard(View edCount){

        //设置可获得焦点
        edCount.setFocusable(true);
        edCount.setFocusableInTouchMode(true);
        //请求获得焦点
        edCount.requestFocus();
        //调用系统输入法
        InputMethodManager imm = (InputMethodManager) StyledDialog.context.getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.showSoftInput(edCount,InputMethodManager.RESULT_SHOWN);
    }

    public static void hideKeyBorad(ConfigBean bean){
        if(!bean.needSoftKeyboard){
            return;
        }
        if(bean.viewHolder !=null){
            bean.viewHolder.hideKeyBoard();
        }
        if(bean.customContentHolder !=null){
            bean.customContentHolder.hideKeyBoard();
        }
    }



    public static void hideKeyBoard(View view){
        InputMethodManager imm = (InputMethodManager) StyledDialog.context.getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(view.getWindowToken(), 0); //强制隐藏键盘
    }
    public static void hideKeyBoard(Window window){
        InputMethodManager imm = (InputMethodManager) StyledDialog.context.getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(window.getDecorView().getWindowToken(), 0); //强制隐藏键盘
    }


    public static void removeFromParent(View customView) {
        ViewParent parent =  customView.getParent();
        if(parent !=null){
            ViewGroup group = (ViewGroup) parent;
            group.removeView(customView);
        }
    }
} public abstract class SuperLvAdapter extends BaseAdapter implements Refreshable ,ILifeCycle{
    List datas;
    Context context;
    boolean isListViewFling;

    public boolean isListViewFling() {
        return isListViewFling;
    }

    public void setListViewFling(boolean listViewFling) {
        isListViewFling = listViewFling;
    }


    public SuperLvAdapter(Context context){
        this.datas = new ArrayList();
        this.context = context;
    }
    @Override
    public int getCount() {
        if (datas == null )
        return 0;
        return datas.size();
    }



    @Override
    public Object getItem(int position) {
        if (datas == null)
        return null;
        return datas.get(position);
    }

    @Override
    public long getItemId(int position) {
        if (datas == null){
            return 0;
        }
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        SuperLvHolder holder = null;
        if (convertView == null){
            holder = generateNewHolder(context,getItemViewType(position));
            convertView = holder.rootView;
            convertView.setTag(holder);
        }else {
            holder = (SuperLvHolder) convertView.getTag();
        }
        holder.assingDatasAndEvents(context,datas.get(position),position,position == getCount() -1,isListViewFling,datas,this);
        return convertView;
    }

    protected abstract SuperLvHolder generateNewHolder(Context context, int itemViewType);
    @Override
    public void refresh(List newData){
        if (newData == null){
            datas.clear();
            notifyDataSetChanged();
            return;
        }
        if (datas == null){
            datas = newData;
            notifyDataSetChanged();
        }else {
            datas.clear();
            datas.addAll(newData);
            notifyDataSetChanged();
        }
    }
    @Override
    public void addAll(List newData){
        if (newData == null){
            return;
        }
        if (datas == null){
            datas = newData;
            notifyDataSetChanged();
        }else {
            datas.addAll(newData);
            notifyDataSetChanged();
        }
    }
    @Override
    public void clear(){
        if (datas != null){
            datas.clear();
            notifyDataSetChanged();
        }
    }
    @Override
    public void delete(int position){
        if (datas != null && position < getCount()){
            datas.remove(position);
            notifyDataSetChanged();
        }
    }
    public List getListData(){
        return datas;
    }

    @Override
    public void add(Object object) {
        if (object ==null)
            return;
        try {
            datas.add(object);
            notifyDataSetChanged();
        }catch (Exception e){

        }
    }

    @Override
    public void onDestory() {

    }
} public abstract class SuperLvHolder<T> implements View.OnAttachStateChangeListener,ILifeCycle{
    public View rootView;

    /*public SuperLvHolder(){

    }*/

    public SuperLvHolder(Context context){
        if(setLayoutRes() !=0){
            rootView = View.inflate(context,setLayoutRes(),null);
        }else {
            rootView = setRootView(context);
        }
        rootView.addOnAttachStateChangeListener(this);

        //ButterKnife.bind(this,rootView);
        findViews();
    }

    protected View setRootView(Context context) {
        return null;
    }

    protected abstract void findViews();

    protected abstract  @LayoutRes  int setLayoutRes();

    /**
     * 一般情况下，实现这个方法就足够了
     * if use as custom view holder ,the bean will return as null,do not use it
     * @param context
     * @param bean
     */
    public  abstract void assingDatasAndEvents(Context context, @Nullable T bean);

    public void showKeyBoard(){

    }

    public void hideKeyBoard(){

    }

    /**
     * 如果有需要，才实现这个方法
     * @param context activity实例,用于一些点击事件
     * @param bean 该条目的数据
     * @param position 该条目所在的位置
     * @param isLast 是否为最后一条,有些情况下需要用到
     * @param isListViewFling listview是不是在惯性滑动,备用
     *  @param datas 整个listview对应的数据
     * @param superAdapter adapter对象引用,可用于触发notifydatesetChanged()方法刷新整个listview,比如更改的单选按钮
     */
    public void assingDatasAndEvents(Context context, T bean, int position , boolean isLast,
                                     boolean isListViewFling, List datas, SuperLvAdapter superAdapter){
        assingDatasAndEvents(context,bean);
    }

    @Override
    public void onViewAttachedToWindow(View v) {

    }

    @Override
    public void onViewDetachedFromWindow(View v) {

    }

    @Override
    public void onDestory() {

    }
} public class BottomSheetBean {
    public @DrawableRes  int icon;
    public String text;

    public BottomSheetBean(){

    }

    public BottomSheetBean(int icon, String text) {
        this.icon = icon;
        this.text = text;
    }
} public  class MyDialogBuilder {

    protected static int singleChosen;
   protected  ConfigBean buildByType(ConfigBean bean){

        Tool.fixContext(bean);

       switch (bean.type){
           case DefaultConfig.TYPE_MD_LOADING:
               Tool.newCustomDialog(bean);
               buildMdLoading(bean);
               break;
           case DefaultConfig.TYPE_PROGRESS:
               buildProgress(bean);
               break;
           case DefaultConfig.TYPE_MD_ALERT:
           case DefaultConfig.TYPE_MD_INPUT:
               if(bean.context instanceof Activity && !bean.showAsActivity){
                   buildMdAlert(bean);
               }else {
                   buildMyMd(bean);
               }

               break;
           case DefaultConfig.TYPE_MD_SINGLE_CHOOSE:
               if(bean.context instanceof Activity && !bean.showAsActivity){
                   buildMdSingleChoose(bean);
               }else {
                   buildMyMd(bean);
               }

               break;
           case DefaultConfig.TYPE_MD_MULTI_CHOOSE:
               if(bean.context instanceof Activity && !bean.showAsActivity){
                   buildMdMultiChoose(bean);
               }else {
                   buildMyMd(bean);
               }

               break;
           case DefaultConfig.TYPE_IOS_HORIZONTAL:
               Tool.newCustomDialog(bean);
               buildIosAlert(bean);
               break;
           case DefaultConfig.TYPE_IOS_VERTICAL:
               Tool.newCustomDialog(bean);
               buildIosAlertVertical(bean);
               break;
           case DefaultConfig.TYPE_IOS_BOTTOM:
               Tool.newCustomDialog(bean);
               buildBottomItemDialog(bean);
               break;
           case DefaultConfig.TYPE_IOS_INPUT:
               Tool.newCustomDialog(bean);
               buildNormalInput(bean);
               break;
           case DefaultConfig.TYPE_IOS_CENTER_LIST:
               Tool.newCustomDialog(bean);
               buildIosSingleChoose(bean);
               break;
           case DefaultConfig.TYPE_CUSTOM_VIEW:
               Tool.newCustomDialog(bean);
               View rootView = getCustomRootView(bean);
               bean.dialog.setContentView(rootView);
               break;
           case DefaultConfig.TYPE_BOTTOM_SHEET_CUSTOM:
              buildBottomSheet(bean);


               break;
           case DefaultConfig.TYPE_BOTTOM_SHEET_LIST:
               buildBottomSheetLv(bean);


               break;
           case DefaultConfig.TYPE_BOTTOM_SHEET_GRID:
               buildBottomSheetLv(bean);

               break;

           case DefaultConfig.TYPE_IOS_LOADING:
               Tool.newCustomDialog(bean);
               buildLoading(bean);
               break;
          default:
              break;


       }

       Dialog dialog = bean.dialog ==null ? bean.alertDialog : bean.dialog;
       Window window = dialog.getWindow();
       window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
       Tool.setWindowAnimation(window, bean);
       Tool.setCancelable(bean);
       Tool.setListener(dialog,bean);

       Tool.adjustStyle(bean);
       return bean;
   }

    private View getCustomRootView(ConfigBean bean) {

        if(bean.customContentHolder!=null){
            Tool.removeFromParent(bean.customContentHolder.rootView);
            if(bean.asAdXStyle){
                AdXHolder adXHolder = new AdXHolder(bean.context);
                adXHolder.assingDatasAndEvents(bean.context,bean);
                return adXHolder.rootView;
            }
            return bean.customContentHolder.rootView;
        }else {
            Tool.removeFromParent(bean.customView);
            if(bean.asAdXStyle){
                AdXHolder adXHolder = new AdXHolder(bean.context);
                adXHolder.assingDatasAndEvents(bean.context,bean);
                return adXHolder.rootView;
            }
            return bean.customView;

        }
    }

    private void buildMyMd(ConfigBean bean) {
        Tool.newCustomDialog(bean);
        MaterialDialogHolder holder = new MaterialDialogHolder(bean.context);
        bean.viewHolder = holder;
        holder.assingDatasAndEvents(bean.context,bean);
        bean.dialog.setContentView(holder.rootView);
    }


    private void buildProgress(ConfigBean bean) {
        ProgressDialog dialog = new ProgressDialog(bean.context);
        dialog.setTitle("");
        dialog.setMessage(bean.msg);
        dialog.setProgressStyle(bean.isProgressHorzontal ? ProgressDialog.STYLE_HORIZONTAL:ProgressDialog.STYLE_SPINNER);
        dialog.setIndeterminate(false);
        bean.dialog = dialog;
    }



    private void buildBottomSheetLv(final ConfigBean bean) {
         Dialog dialog = null;
       if(bean.hasBehaviour){
            dialog = new RightMdBottomSheetDialog(bean.context);
           bean.forceWidthPercent = 1.0f;
       }else {
           Tool.newCustomDialog(bean);
           dialog = bean.dialog;
           bean.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
           bean.forceWidthPercent = 1.0f;
           bean.bgRes = R.color.dialogutil_bg_white;
       }
        bean.dialog = dialog;


        if(bean.bottomSheetStyle ==null){
            bean.bottomSheetStyle =  BottomSheetStyle.newBuilder().build();
        }

        BottomSheetHolder bottomSheetHolder = new BottomSheetHolder(bean.context);
        bottomSheetHolder.assingDatasAndEvents(bean.context,bean);
        bean.viewHolder = bottomSheetHolder;

        dialog.setContentView(bottomSheetHolder.rootView);


    }

    private void buildBottomSheet(ConfigBean bean) {
        final BottomSheetDialog dialog = new BottomSheetDialog(bean.context);
        Tool.removeFromParent(bean.customView);
        dialog.setContentView(bean.customView);
        bean.forceWidthPercent = 1.0f;
        dialog.setCancelable(bean.cancelable);
        dialog.setCanceledOnTouchOutside(bean.outsideTouchable);
        bean.dialog = dialog;
    }

    protected  ConfigBean buildLoading(ConfigBean bean){
        View root = View.inflate(bean.context, R.layout.loading,null);
        ImageView gifMovieView = (ImageView) root.findViewById(R.id.iv_loading);
        AnimationDrawable drawable = (AnimationDrawable) gifMovieView.getDrawable();
        if(drawable!=null){
            drawable.start();
        }
        TextView tvMsg = (TextView) root.findViewById(R.id.loading_msg);
        tvMsg.setText(bean.msg);
        bean.dialog.setContentView(root);
        return bean;
    }


    protected  ConfigBean buildMdLoading(ConfigBean bean){
        View root = View.inflate(bean.context, R.layout.progressview_wrapconent,null);
        TextView tvMsg = (TextView) root.findViewById(R.id.loading_msg);
        tvMsg.setText(bean.msg);
        bean.dialog.setContentView(root);
        return bean;
    }

    protected  ConfigBean buildMdAlert(final ConfigBean bean){
        Tool.fixContext(bean);
        final AlertDialog.Builder builder = new AlertDialog.Builder(bean.context);
        if(bean.customContentHolder ==null){
            if(bean.type == DefaultConfig.TYPE_MD_INPUT){
                MdInputHolder holder = new MdInputHolder(bean.context);
                bean.viewHolder = holder;
                bean.setNeedSoftKeyboard(true);
                holder.assingDatasAndEvents(bean.context,bean);
                builder.setView(bean.viewHolder.rootView);
            }else {
                builder.setMessage(bean.msg);
            }

        }else {
            builder.setView(bean.customContentHolder.rootView);
            //bean.customContentHolder.assingDatasAndEvents(Tool.fixContext(bean).context,bean);
        }
        builder.setTitle(bean.title)
                .setPositiveButton(bean.text1, null)//不让点击默认消失，而是做出判断，见Tool.setMdBtnStytle
                .setNegativeButton(bean.text2, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        bean.listener.onSecond();
                        Tool.hideKeyBorad(bean);
                        dialog.dismiss();
                    }
                }).setNeutralButton(bean.text3, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            bean.listener.onThird();
                            Tool.hideKeyBorad(bean);
                            dialog.dismiss();
                        }
        });
        AlertDialog dialog = builder.create();
        
        dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
                Tool.hideKeyBorad(bean);
                if(bean.listener!=null)
                bean.listener.onCancle();
            }
        });

        dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
            @Override
            public void onDismiss(DialogInterface dialog) {
                if(bean.listener !=null){
                    bean.listener.onDismiss();
                }
            }
        });


        bean.alertDialog = dialog;
        return bean;
    }

    protected  ConfigBean buildMdSingleChoose(final ConfigBean bean){
        AlertDialog.Builder builder = new AlertDialog.Builder(bean.context);
        singleChosen = bean.defaultChosen;
        builder.setTitle(bean.title)
                .setPositiveButton(bean.text1, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {

                        if (bean.listener != null){
                            bean.listener.onFirst();
                            bean.listener.onGetChoose(singleChosen,bean.wordsMd[singleChosen]);
                        }
                        Tool.dismiss(bean,true);
                    }
                })
                .setNegativeButton(bean.text2, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        if (bean.listener != null){
                            bean.listener.onSecond();
                        }
                        Tool.dismiss(bean);
                    }
                })
                .setSingleChoiceItems( bean.wordsMd, bean.defaultChosen, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        singleChosen = i;
                        if (bean.itemListener != null){
                            bean.itemListener.onItemClick(bean.wordsMd[i],i);
                        }
                        Tool.dismiss(bean,true);

                    }
                });

        AlertDialog dialog = builder.create();// crash when context is not activity
        bean.alertDialog = dialog;
        //dialog.getWindow().getDecorView()
       // addShaow(bean,dialog);


        return bean;
    }



    protected  ConfigBean buildMdMultiChoose(final ConfigBean bean){
        AlertDialog.Builder builder = new AlertDialog.Builder(bean.context);
        builder.setTitle(bean.title)
                .setCancelable(true)
                .setPositiveButton(bean.text1, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        if (bean.listener != null){
                            bean.listener.onFirst();
                            bean.listener.onGetChoose(bean.checkedItems);
                            List<Integer> selectedIndex = new ArrayList<Integer>();
                            List<CharSequence> selectedStrs = new ArrayList<CharSequence>();
                            for(int j=0;j<bean.checkedItems.length;j++){
                                if(bean.checkedItems[j]){
                                    selectedIndex.add(j);
                                    selectedStrs.add(bean.wordsMd[j]);
                                }
                            }
                            bean.listener.onChoosen(selectedIndex,selectedStrs,bean.checkedItems);
                        }
                        Tool.dismiss(bean,true);
                    }
                })
                .setNegativeButton(bean.text2, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        if (bean.listener != null){
                            bean.listener.onSecond();
                        }
                        Tool.dismiss(bean);
                    }
                })
                .setMultiChoiceItems(bean.wordsMd, bean.checkedItems, new DialogInterface.OnMultiChoiceClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i, boolean b) {

                    }
                })
        ;

        AlertDialog dialog = builder.create();
        bean.alertDialog = dialog;
        return bean;
    }

    protected  ConfigBean buildIosAlert(ConfigBean bean){
        bean.isVertical = false;
        bean.hint1 = "";
        bean.hint2 = "";
        buildIosCommon(bean);
        return bean;
    }

    protected  ConfigBean buildIosAlertVertical(ConfigBean bean){
        bean.isVertical = true;
        bean.hint1 = "";
        bean.hint2 = "";
        buildIosCommon(bean);
        return bean;
    }

    protected  ConfigBean buildIosSingleChoose(ConfigBean bean){
        IosCenterItemHolder holder = new IosCenterItemHolder(bean.context);
        bean.viewHolder = holder;

        bean.dialog.setContentView(holder.rootView);
        holder.assingDatasAndEvents(bean.context,bean);

        bean.viewHeight = Tool.mesureHeight(holder.rootView,holder.lv);

        Window window = bean.dialog.getWindow();
        window.setGravity(Gravity.CENTER);
        return bean;
    }

    protected  ConfigBean buildBottomItemDialog(ConfigBean bean){
        IosActionSheetHolder holder = new IosActionSheetHolder(bean.context);
        bean.viewHolder = holder;
        bean.dialog.setContentView(holder.rootView);

        holder.assingDatasAndEvents(bean.context,bean);

        bean.viewHeight = Tool.mesureHeight(holder.rootView,holder.lv);

        Window window = bean.dialog.getWindow();
        window.setGravity(Gravity.BOTTOM);
        window.setWindowAnimations(R.style.mystyle);
        return bean;
    }


    protected  ConfigBean buildNormalInput(ConfigBean bean){
        buildIosCommon(bean);
        return bean;
    }

    private ConfigBean buildIosCommon(ConfigBean bean){

        IosAlertDialogHolder holder = new IosAlertDialogHolder(bean.context);
        bean.viewHolder = holder;
        bean.dialog.setContentView(holder.rootView);
        holder.assingDatasAndEvents(bean.context,bean);

        int height = Tool.mesureHeight(holder.rootView,holder.tvMsg,holder.et1,holder.et2);
        bean.viewHeight = height;


        return bean;

    }







    
} public abstract class MyDialogListener {

    /**
     * md-positive button ,ios-first button
     */
    public abstract void onFirst();//

    /**
     * md-negative button,ios-second
     */
    public abstract void onSecond();//
    public void onThird(){}//md-netural,ios-第三个

    public void onCancle(){}

    public void onDismiss(){}

    /**
     * 可以在这里弹出键盘
     */
    public void onShow(){}





    /**
     * 提供给Input的回调
     * @param input1
     * @param input2
     */
    public void onGetInput(CharSequence input1,CharSequence input2){

    }


    /**
     * 每次点击btn1,则传回输入值以便校验
     * @param input1
     * @param input2
     * @param editText1
     * @param editText2
     * @return
     */
    public boolean onInputValid(CharSequence input1, CharSequence input2, EditText editText1,EditText editText2){
        return true;
    }

    /**
     * 提供给MdSingleChoose的回调
     * @param chosenIdx
     * @param chosenTxt
     */
    public void onGetChoose(int chosenIdx,CharSequence chosenTxt){

    }

    /**
     * 提供给MdMultiChoose的回调
     * @param states
     */
    @Deprecated
    public void onGetChoose(boolean[] states){

    }

    /**
     * 提供给MdMultiChoose的更详细的回调
     * @param selectedIndex
     * @param selectedStrs
     * @param states
     */
    public void onChoosen( List<Integer> selectedIndex, List<CharSequence> selectedStrs,boolean[] states){

    }


} public abstract class MyItemDialogListener {


    /**
     * IosSingleChoose,BottomItemDialog的点击条目回调
     * @param text
     * @param position
     */
   public abstract void onItemClick(CharSequence text, int position);


    /**
     * BottomItemDialog的底部按钮(经常是取消)的点击回调
     */
   public void onBottomBtnClick(){}

} public interface Styleable {

    ConfigBean setBtnColor(@ColorRes int btn1Color, @ColorRes int btn2Color, @ColorRes int btn3Color);

    ConfigBean setListItemColor(@ColorRes int lvItemTxtColor,Map<Integer,Integer> colorOfPosition);

    ConfigBean setTitleColor(@ColorRes int colorRes);
    ConfigBean setMsgColor(@ColorRes int colorRes);
    ConfigBean seInputColor(@ColorRes int colorRes);



    ConfigBean setTitleSize(int sizeInSp);
    ConfigBean setMsgSize(int sizeInSp);
    ConfigBean setBtnSize(int sizeInSp);
    ConfigBean setLvItemSize(int sizeInSp);
    ConfigBean setInputSize(int sizeInSp);

    Dialog show();

    //内容设置
    ConfigBean setBtnText(CharSequence btn1Text, @Nullable CharSequence btn2Text, @Nullable CharSequence btn3Text);

    ConfigBean setBtnText(CharSequence positiveTxt, @Nullable CharSequence negtiveText);
    ConfigBean setBtnText(CharSequence positiveTxt);

    ConfigBean setListener(MyDialogListener listener);



    ConfigBean setCancelable(boolean cancelable,boolean outsideCancelable);







} public class DialogUtilDialogFragment extends DialogFragment {
    protected  View myRootView;

    protected ConfigBean bean;

    public void setConfigbean(ConfigBean bean){
        this.bean = bean;

    }


    public void setRootView(View rootView){
        this.myRootView = rootView;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {

        getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE); //去除标题栏
        getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));

        //getDialog().setCancelable(true);
        getDialog().setCanceledOnTouchOutside(true);

        getDialog().setOnKeyListener(new DialogInterface.OnKeyListener() {
            @Override
            public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
                    if(bean.cancelable){
                        DialogUtilDialogFragment.this.dismiss();
                        return true;
                    }
                }
                return false;
            }
        });
        return myRootView;
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        if(bean.alertDialog !=null){
            return bean.alertDialog;
        }
        return super.onCreateDialog(savedInstanceState);
    }


    /**
     * 此处更改宽高
     */
    @Override
    public void onStart() {
        super.onStart();

        Window window = getDialog().getWindow();
        WindowManager.LayoutParams lp = window.getAttributes();
        lp.gravity = bean.gravity; //底部

        window.setAttributes(lp);
        Tool.adjustWH(getDialog(),bean);

//设置对话框宽高也可以使用lp.width和lp.height
    }
} public class DialogUtil_DialogActivity extends Activity {

    ConfigBean bean;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


    }

    public void show(ConfigBean bean){
        this.bean = bean;
        View view = null;
        if(bean.dialog !=null){
            view =bean.dialog.getWindow().getDecorView();
        }else if(bean.alertDialog !=null){
            view = bean.alertDialog.getWindow().getDecorView();
        }
        if(view!=null){
            setContentView(view);
            WindowAdjuster.adjust(getWindow(),bean);
            bean.listener.onShow();
        }else {
            finish();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(bean!=null && bean.homeKeyReceiver!=null){
            try {
                unregisterReceiver(bean.homeKeyReceiver);
            }catch (Exception e){
                e.printStackTrace();
            }

        }
    }

    @Override
    public void onBackPressed() {

        if(bean.cancelable){
            super.onBackPressed();
        }

    }
}
import android.app.Activity;
import android.app.Dialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Looper;
import android.support.annotation.ColorRes;
import android.support.annotation.DrawableRes;
import android.support.annotation.FloatRange;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.support.v7.app.AlertDialog;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import com.hss01248.dialog.ActivityStackManager;
import com.hss01248.dialog.StyledDialog;
import com.hss01248.dialog.Tool;
import com.hss01248.dialog.adapter.SuperLvAdapter;
import com.hss01248.dialog.adapter.SuperLvHolder;
import com.hss01248.dialog.bottomsheet.BottomSheetBean;
import com.hss01248.dialog.building.MyDialogBuilder;
import com.hss01248.dialog.interfaces.MyDialogListener;
import com.hss01248.dialog.interfaces.MyItemDialogListener;
import com.hss01248.dialog.interfaces.Styleable;
import com.hss01248.dialog.view.DialogUtilDialogFragment;
import com.hss01248.dialog.view.DialogUtil_DialogActivity;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
        return this;
    }

    public ConfigBean setBackground(int bgRes) {
        this.bgRes = bgRes;
        useTheShadowBg = false;
        return this;
    }

    /**
     * default background res: R.drawable.shadow,white background ,surround with shadow
     *
     * @param useTheWhiteAndShadowBg default is true. set false to disable the shadow background ,and set your own background in your xml
     * @return
     */
    public ConfigBean setHasShadow(boolean useTheWhiteAndShadowBg) {
        if (bgRes > 0) {
            return this;
        }
        this.useTheShadowBg = useTheWhiteAndShadowBg;
        return this;
    }

    @Override
    public ConfigBean setBtnColor(@ColorRes int btn1Color, @ColorRes int btn2Color, @ColorRes int btn3Color) {
        if (btn1Color != 0)
            this.btn1Color = btn1Color;
        if (btn2Color != 0)
            this.btn2Color = btn2Color;
        if (btn3Color != 0)
            this.btn3Color = btn3Color;
        return this;
    }

    @Override
    public ConfigBean setListItemColor(@ColorRes int lvItemTxtColor, Map<Integer, Integer> colorOfPosition) {
        if (lvItemTxtColor != 0)
            this.lvItemTxtColor = lvItemTxtColor;
        if (colorOfPosition != null && colorOfPosition.size() > 0) {
            this.colorOfPosition = colorOfPosition;
        }
        return this;
    }

    @Override
    public ConfigBean setTitleColor(@ColorRes int colorRes) {
        if (colorRes != 0) {
            this.titleTxtColor = colorRes;
        }
        return this;
    }

    @Override
    public ConfigBean setMsgColor(@ColorRes int colorRes) {
        if (colorRes != 0) {
            this.msgTxtColor = colorRes;
        }
        return this;
    }

    public ConfigBean setActivity(Activity activity) {
        this.context = activity;
        return this;
    }

    @Override
    public ConfigBean seInputColor(@ColorRes int colorRes) {
        if (colorRes > 0) {
            this.inputTxtColor = colorRes;
        }
        return this;
    }

    @Override
    public ConfigBean setTitleSize(int sizeInSp) {
        if (sizeInSp > 0 && sizeInSp < 30) {
            this.titleTxtSize = sizeInSp;
        }
        return this;
    }

    @Override
    public ConfigBean setMsgSize(int sizeInSp) {
        if (sizeInSp > 0 && sizeInSp < 30) {
            this.msgTxtSize = sizeInSp;
        }
        return this;
    }

    /**
     * 最大30sp
     *
     * @param sizeInSp
     * @return
     */
    @Override
    public ConfigBean setBtnSize(int sizeInSp) {
        if (sizeInSp > 0 && sizeInSp < 30) {
            this.btnTxtSize = sizeInSp;
        }
        return this;
    }

    @Override
    public ConfigBean setLvItemSize(int sizeInSp) {
        if (sizeInSp > 0 && sizeInSp < 30) {
            this.itemTxtSize = sizeInSp;
        }
        return this;
    }

    @Override
    public ConfigBean setInputSize(int sizeInSp) {
        if (sizeInSp > 0 && sizeInSp < 30) {
            this.inputTxtSize = sizeInSp;
        }
        return this;
    }

    private void showAsActivityNow() {
        Activity activity = ActivityStackManager.getInstance().getTopActivity();