自定义带背景色的Dialog

说在前面

在项目中经常会用到dialog,我们项目中也用到了dialog,设计师特地标识了背景为
#CC272B3C80%透明度的蓝黑背景,长这样,80%的透明背景看不出来,大家感受没有透明度的吧:

自定义带背景色的Dialog_第1张图片
设计师标记的颜色.png

一看这颜色,不就改变下背景嘛

@color/cc272b3c
true

改完后运行发现颜色并没有改变,瞬间惊呆,原来木有用。
查阅资料发现windowBackground改变的是dialog自身背景的颜色,而backgroundDimEnabled只能调节页面背景暗或者亮。既然这样那我就把dialog调整为全屏大小,再在dialog中加入viewgroup不就可以了嘛,说干咱抄起家活就干起来:

资源文件

  • 首先设置xml的style,需要把dialog背景设置为透明,页面背景设置高亮

    
    
  • 需要一个只带空的framelayout布局

    
    
    
    

java类

  • 自定义dialog

    public abstract class BaseDialog extends Dialog {
    
      protected View dView;
      /**
       * 编辑资料页面需要点击阴影部分dialog消失
       * 提供外部调用root布局设置点击事件
       */
      private FrameLayout mFlRootView;
    
      public BaseDialog(Context context, int gravity) {
          this(context, R.style.CustomerDialog, gravity);
      }
    
      public View getRootView() {
          return dView;
      }
    
      private int mGravity;
    
      public BaseDialog(Context context, int style, int gravity) {
          super(context, style);
          requestWindowFeature(Window.FEATURE_NO_TITLE);
          super.setContentView(R.layout.dialog_base);
          this.mGravity = gravity;
    
          dView = getView();
          setContentView(dView);
    
          Window dialogWindow = getWindow();
          if (null != dialogWindow) {
              dialogWindow.setLayout(WindowManager.LayoutParams.MATCH_PARENT,
                      WindowManager.LayoutParams.MATCH_PARENT);
              WindowManager.LayoutParams lp = dialogWindow.getAttributes();
              lp.windowAnimations = R.style.no_dialog_exit;
              dialogWindow.setAttributes(lp);
          }
      }
    
      /**
       * 获取页面布局
       *
       * @return 页面布局资源
       */
      public abstract View getView();
    
      /**
       * 供外部调用跟布局使用
       * @return view
       */
      public View getFlRootView() {
          return mFlRootView;
      }
    
      @Override
      public void setContentView(int layoutId) {
          setContentView(View.inflate(getContext(), layoutId, null));
      }
    
      @Override
      public void setContentView(View view) {
          mFlRootView = (FrameLayout) findViewById(R.id.fLRootView);
          if (mFlRootView == null || view == null) {
              return;
          }
          FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
                  ViewGroup.LayoutParams.MATCH_PARENT,
                  ViewGroup.LayoutParams.WRAP_CONTENT);
          if (mGravity != 0) {
              layoutParams.gravity = mGravity;
          }
          mFlRootView.addView(view, layoutParams);
          mFlRootView.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                //todo something
              }
          });
      }
    
      private boolean mCancelable = true;
    
      @Override
      public void setCancelable(boolean flag) {
          super.setCancelable(flag);
          mCancelable = flag;
      }
    }
    

    我们需要自己用的dialog可以通过继承basedialog重写getview()方法传入我们需要的布局

增加动画

  • 这边有个大兄弟说了,这样传入的view,不就没有动画了嘛!
    这位兄台说的是呢,那么我们现在就加入动画

    首先声明下,我这里传的是dialog显示时候向上滑动,消失向下慢慢隐藏,你们可以根据需求传入

    不罗嗦,直接上代码

     private Animation llBottomIn;
     private Animation llBottomOut;
    
     private void initAnimatorIn() {
         if (llBottomIn == null) {
             llBottomIn = AnimationUtils.loadAnimation(getContext(), R.anim.slide_in_bottom);
         }
         dView.startAnimation(llBottomIn);
     }
    
     private void initAnimatorOut() {
         if (llBottomOut == null) {
             llBottomOut = AnimationUtils.loadAnimation(getContext(), R.anim.slide_out_bottom);
         }
         dView.startAnimation(llBottomOut);
     }
    
     /**
      * 显示或隐藏dialog
      * @param show true 显示 false 隐藏
      */
     public void showDialogWithAnim(boolean show) {
         if (show) {
             initAnimatorIn();
             dView.setVisibility(View.VISIBLE);
             mHandler.sendEmptyMessage(SHOW_DIALOG);
         } else {
             initAnimatorOut();
             dView.setVisibility(View.INVISIBLE);
             mHandler.sendEmptyMessageDelayed(DISMISS_DIALOG, show_delayed);
         }
     }
    
     @Override
     public void dismiss() {
         if (mHandler != null) {
             mHandler.removeMessages(SHOW_DIALOG);
             mHandler.removeMessages(DISMISS_DIALOG);
         }
         super.dismiss();
     }
    
     private final static int SHOW_DIALOG = 0xFF;
     public final static int DISMISS_DIALOG = 0xFE;
     private final static int show_delayed = 300;
    
     /**
      * 实例化一个MyHandler对象
      * 自定义static handler是防止内存泄漏
      */
     private DialogHandler mHandler = new DialogHandler(this);
    
     public DialogHandler getHandler() {
         if (mHandler == null) {
             mHandler = new DialogHandler(this);
         }
         return mHandler;
     }
    
     public static class DialogHandler extends Handler {
    
         WeakReference dialogWeakReference;
         BaseDialog dialog;
    
         DialogHandler(BaseDialog dialog) {
             dialogWeakReference = new WeakReference<>(dialog);
             this.dialog = dialogWeakReference.get();
         }
    
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
                 case SHOW_DIALOG:
                     dialog.show();
                     break;
    
                 case DISMISS_DIALOG:
                     dialog.dismiss();
                     break;
    
                 default:
                     break;
             }
         }
     }
    

    子类需要显示或隐藏直接调用showDialogWithAnim()方法即可。

    到这就结束了,只是记录下自己用的,方便以后查看,欢迎大家指教~

你可能感兴趣的:(自定义带背景色的Dialog)