BaseDialog.java 11.6 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412
package com.xdy.ui.dialog;

import android.app.Dialog;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager.LayoutParams;
import android.widget.LinearLayout;

import com.xdy.util.DisplayUtil;
import com.nineoldandroids.animation.Animator;

import java.lang.ref.WeakReference;

//                            _ooOoo_
//                           o8888888o
//                            88"  .   "88
//                            (|   -_-  |)
//                            O\  =  /O
//                         ____/`---'\____
//                          . ' \\| |// `.
//                        / \\||| : |||// \
//                      / _||||| -:- |||||- \
//                        | | \\\ - /// | |
//                      | \_| ''\---/'' | |
//                      \ .-\__ `-` ___/-. /
//                   ___`. .' /--.--\ `. . __
//              ."" '< `.___\_<|>_/___.' >'"".
//              | | : `- \`.;`\ _ /`;.`/ - ` : | |
//              \ \ `-. \_ __\ /__ _/ .-` / /
//          ======`-.____`-.___\_____/___.-`____.-'======
//                            `=---='
//         .............................................
//                  佛祖保佑             永无BUG
//          佛曰:
//                写字楼里写字间,写字间里程序员;
//                程序人员写程序,又拿程序换酒钱。
//                酒醒只在网上坐,酒醉还来网下眠;
//                酒醉酒醒日复日,网上网下年复年。
//                但愿老死电脑间,不愿鞠躬老板前;
//                奔驰宝马贵者趣,公交自行程序员。
//                别人笑我忒疯癫,我笑自己命太贱;
//                不见满街漂亮妹,哪个归得程序员?
public abstract class BaseDialog extends Dialog {
    /**
     * TAG(日志)
     */
    protected String TAG;
    /**
     * context(上下文)
     */
    protected WeakReference<Context> context;
    /**
     * (DisplayMetrics)设备密度
     */
    protected DisplayMetrics dm;
    /**
     * enable dismiss outside dialog(设置点击对话框以外区域,是否dismiss)
     */
    protected boolean cancel;
    /**
     * dialog width scale(宽度比例)
     */
    protected float widthScale = 1;
    /**
     * dialog height scale(高度比例)
     */
    protected float heightScale;
    /**
     * showAnim(对话框显示动画)
     */
    private BaseAnimatorSet showAnim;
    /**
     * dismissAnim(对话框消失动画)
     */
    private BaseAnimatorSet dismissAnim;
    /**
     * top container(最上层容器)
     */
    protected LinearLayout ll_top;
    /**
     * container to control dialog height(用于控制对话框高度)
     */
    protected LinearLayout ll_control_height;
    /**
     * is showAnim running(显示动画是否正在执行)
     */
    private boolean isShowAnim;
    /**
     * is DismissAnim running(消失动画是否正在执行)
     */
    private boolean isDismissAnim;
    /**
     * max height(最大高度)
     */
    protected float maxHeight;

    /**
     * dialog是否可以移动
     */
    private boolean isMove = true;

    /**
     * method execute order:
     * show:constrouctor---show---oncreate---onStart---onAttachToWindow
     * dismiss:dismiss---onDetachedFromWindow---onStop
     *
     * @param context
     */
    public BaseDialog(Context context) {
        super(context);
        setDialogTheme();
        this.context = new WeakReference<Context>(context);
        this.TAG = this.getClass().getSimpleName();
        Log.d(TAG, "constructor");
    }


    /**
     * set dialog theme(设置对话框主题)
     */
    private void setDialogTheme() {
        requestWindowFeature(Window.FEATURE_NO_TITLE);// android:windowNoTitle
        getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));// android:windowBackground
        getWindow().addFlags(LayoutParams.FLAG_DIM_BEHIND);// android:backgroundDimEnabled默认是true的
    }

    /**
     * inflate layout for dialog ui and return (填充对话框所需要的布局并返回)
     * <pre>
     *
     * public View onCreateView() {
     * View inflate = View.inflate(context, R.layout.dialog_share, null);
     * return inflate;
     * }
     * </pre>
     */
    public abstract View onCreateView();

    /**
     * set Ui data or logic opreation before attatched window(在对话框显示之前,设置界面数据或者逻辑)
     *
     * @return true dialog show,fasle dialog not show
     */
    public abstract boolean setUiBeforShow();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.d(TAG, "onCreate");
        dm = context.get().getResources().getDisplayMetrics();
        ll_top = new LinearLayout(context.get());
        ll_top.setGravity(Gravity.CENTER);

        ll_control_height = new LinearLayout(context.get());
        ll_control_height.setOrientation(LinearLayout.VERTICAL);

        ll_control_height.addView(onCreateView());
        ll_top.addView(ll_control_height);

        maxHeight = dm.heightPixels - DisplayUtil.getStatusBarHeight(getContext());
        // maxHeight = dm.heightPixels;
        if (isMove) {
            setContentView(ll_top);
        } else {
            setContentView(ll_top, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) maxHeight));
        }
        setCanceledOnTouchOutside(true);

        ll_top.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (cancel) {
                    dismiss();
                }
            }
        });
    }

    /**
     * when dailog attached to window,set dialog width and height and show anim
     * (当dailog依附在window上,设置对话框宽高以及显示动画)
     */
    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
        Log.d(TAG, "onAttachedToWindow");

        setUiBeforShow();

        int width;
        if (widthScale == 0) {
            width = ViewGroup.LayoutParams.WRAP_CONTENT;
        } else {
            width = (int) (dm.widthPixels * widthScale);
        }

        int height;
        if (heightScale == 0) {
            height = ViewGroup.LayoutParams.WRAP_CONTENT;
        } else if (heightScale == 1) {
            height = ViewGroup.LayoutParams.MATCH_PARENT;
        } else {
            height = (int) (maxHeight * heightScale);
        }

        ll_control_height.setLayoutParams(new LinearLayout.LayoutParams(width, height));

        if (showAnim != null) {
            showAnim.listener(new BaseAnimatorSet.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animator) {
                    isShowAnim = true;
                }

                @Override
                public void onAnimationRepeat(Animator animator) {
                }

                @Override
                public void onAnimationEnd(Animator animator) {
                    isShowAnim = false;
                }

                @Override
                public void onAnimationCancel(Animator animator) {
                    isShowAnim = false;
                }
            }).playOn(ll_control_height);
        } else {
            BaseAnimatorSet.reset(ll_control_height);
        }
    }


    @Override
    public void setCanceledOnTouchOutside(boolean cancel) {
        this.cancel = cancel;
        super.setCanceledOnTouchOutside(cancel);
    }

    @Override
    public void show() {
        Log.d(TAG, "show");
        super.show();
    }


    @Override
    protected void onStart() {
        super.onStart();
        Log.d(TAG, "onStart");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d(TAG, "onStop");
    }

    @Override
    public void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        Log.d(TAG, "onDetachedFromWindow");
    }

    @Override
    public void dismiss() {
        Log.d(TAG, "dismiss");
        if (dismissAnim != null)
            dismissAnim.listener(new BaseAnimatorSet.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animator) {
                    isDismissAnim = true;
                }

                @Override
                public void onAnimationRepeat(Animator animator) {
                }

                @Override
                public void onAnimationEnd(Animator animator) {
                    isDismissAnim = false;
                    superDismiss();
                }

                @Override
                public void onAnimationCancel(Animator animator) {
                    isDismissAnim = false;
                    superDismiss();
                }
            }).playOn(ll_control_height);
        else
            superDismiss();
    }

    /**
     * dismiss without anim(无动画dismiss)
     */
    public void superDismiss() {
        super.dismiss();
    }

    /**
     * dialog anim by styles(动画弹出对话框,style动画资源) @param animStyle
     */
    public void show(int animStyle) {
        Window window = getWindow();
        window.setWindowAnimations(animStyle);
        show();
    }

    /**
     * set window dim or not(设置背景是否昏暗)
     *
     * @param isDimEnabled
     * @return BaseDialog
     */
    public BaseDialog dimEnabled(boolean isDimEnabled) {
        if (isDimEnabled) {
            getWindow().addFlags(LayoutParams.FLAG_DIM_BEHIND);
        } else {
            getWindow().clearFlags(LayoutParams.FLAG_DIM_BEHIND);
        }
        return this;
    }

    /**
     * set dialog width scale:0-1(设置对话框宽度,占屏幕宽的比例0-1) @param widthScale @return BaseDialog
     */
    public BaseDialog widthScale(float widthScale) {
        this.widthScale = widthScale;
        return this;
    }

    /**
     * set dialog height scale:0-1(设置对话框高度,占屏幕宽的比例0-1) @param heightScale @return BaseDialog
     */
    public BaseDialog heightScale(float heightScale) {
        this.heightScale = heightScale;
        return this;
    }

    /**
     * set show anim(设置显示的动画) @param showAnim @return BaseDialog
     */
    public BaseDialog showAnim(BaseAnimatorSet showAnim) {
        this.showAnim = showAnim;
        return this;
    }

    /**
     * set dismiss anim(设置隐藏的动画) @param dismissAnim @return BaseDialog
     */
    public BaseDialog dismissAnim(BaseAnimatorSet dismissAnim) {
        this.dismissAnim = dismissAnim;
        return this;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (isDismissAnim || isShowAnim)
            return true;
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public void onBackPressed() {
        if (isDismissAnim || isShowAnim)
            return;
        super.onBackPressed();
    }

    /**
     * dp to px
     *
     * @param dp
     * @return
     */
    protected int dp2px(float dp) {
        final float scale = context.get().getResources().getDisplayMetrics().density;
        return (int) (dp * scale + 0.5f);
    }

    /**
     * @param gravity
     * @brief 设置dialog的位置
     */
    protected void setGravity(int gravity) {
        if (ll_top != null) {
            ll_top.setGravity(gravity);
        }
    }

    /**
     *  dialog位置是否固定
     * @param isMove
     */

    protected void setIsMove(boolean isMove) {
        this.isMove = isMove;
    }


}