注册

DialogX 的一些骚包的高阶使用技巧

DialogX 的一些骚包的高阶使用技巧

DialogX 是一款轻松易用的对话框组件,具备高扩展性和易上手的特点,包含各种自定义主题样式,可以快速实现各式各样的对话框效果,也避免了 AlertDialog 的诸多蛋疼的问题,详情可以参阅这篇文章:《使用 DialogX 快速构建 Android App 对话框》

本篇文章将介绍一些 DialogX 的使用技巧,也欢迎大家集思广益在评论区留下宝贵的建议,DialogX 自始至终的目标都是尽量让开发变得更加简单,基于此目的,DialogX 首先想做的就是避免重复性劳动,一般我们开发产品总会有一些各式各样的需要,比如关于对话框启动和关闭的动画。

局部>组件内>全局生效的属性

局部设置

DialogX 的很多属性都可以自定义调整,最简单的就是通过实例的 set 方法对属性进行调整,例如对于动画,你可以使用这些 set 方法进行调整:

b69641fa87854029ae64d30a9b0b516b~tplv-k3u1fbpfcp-zoom-in-crop-mark:4536:0:0:0.awebp?

但是,当我们的程序中有大量的对话框,但每个 MessageDialog 都需要调整,又不能影响其他对话框的动画,该怎么设置呢?

组件生效

此时就可以使用该对话框的静态方法直接进行设置,例如:

MessageDialog.overrideEnterDuration = 100;    //入场动画时长为100毫秒
MessageDialog.overrideExitDuration = 100;     //出场动画时长为100毫秒
MessageDialog.overrideEnterAnimRes = R.anim.anim_dialogx_top_enter; //入场动画资源
MessageDialog.overrideExitAnimRes = R.anim.anim_dialogx_top_exit;   //出场动画资源

如果要设置的属性想针对全局,也就是所有对话框都生效,此时可以使用全局设置进行调整:

全局设置

你可以随时召唤神龙 DialogX,直接修改静态属性,这里的设置都是针对全局的,可以快速完成需要的调整。

DialogX.enterAnimDuration = 100;
DialogX.exitAnimDuration = 100;

上边演示的是动画相关设置,除此之外,你还可以对对话框的标题文字样式、对话框OK按钮的样式、取消按钮的样式、正文内容的文字样式等等进行全局的调整,只需要知道属性生效的优先级是:

优先级为:实例使用set方法设置 > 组件override设置 > 全局设置。

额外的,如果需要对部分组件的行为进行调整,例如 PopTip 的默认显示位置位于屏幕底部,但产品或设计要求想显示到屏幕中央,但这个设置又取决于主题的限制,此时你可以通过重写主题的设置来实现调整:

覆盖主题设置

想要将 PopTip 吐司提示不按照主题的设定(例如屏幕底部)显示,而是以自己的要求显示(例如屏幕中央),但对于 PopTip 的 align 属性属于主题控制的,此时可以通过重写主题来调整对话框的部分行为,例如:

DialogX.globalStyle = new MaterialStyle(){
   @Override
   public PopTipSettings popTipSettings() {
       return new PopTipSettings() {
           @Override
           public ALIGN align() {
               return ALIGN.CENTER;
          }
      };
  }
};

DialogX 强大的扩展性允许你发挥更多想象空间!如果你的产品经理或者设计师依然不满足于简简单单的动画,想要定制更为丰富的入场/出场效果,此时可以利用 DialogX 预留的对话框动画控制接口对每一个对话框内的组件动画细节进行定制。

完全的动画细节定制

例如,我们可以针对一个对话框的背景遮罩进行透明度动画效果处理,但对于对话框内容部分进行一个从屏幕顶部进入的动画效果,其他的,请发挥你的想象进行设计吧!

使用 DialogXAnimInterface 接口可以完全自定义开启、关闭动画。

由于 DialogX 对话框组件的内部元素都是暴露的,你可以轻松获取并访问内部实例,利用这一点,再加上 DialogXAnimInterface 会负责对话框启动和关闭的动画行为,你可以充分利用它实现你想要的效果。

例如对于一个 CustomDialog,你可以这样控制其启动和关闭动画:

CustomDialog.show(new OnBindView<CustomDialog>(R.layout.layout_custom_dialog) {
           @Override
           public void onBind(final CustomDialog dialog, View v) {
               //...
          }
      })
       //实现完全自定义动画效果
      .setDialogXAnimImpl(new DialogXAnimInterface<CustomDialog>() {
           //启动对话框动画逻辑
           @Override
           public void doShowAnim(CustomDialog customDialog, ObjectRunnable<Float> animProgress) {
               //创建一个资源动画
               Animation enterAnim;
               int enterAnimResId = com.kongzue.dialogx.R.anim.anim_dialogx_top_enter;
               enterAnim = AnimationUtils.loadAnimation(me, enterAnimResId);
               enterAnim.setInterpolator(new DecelerateInterpolator(2f));
               long enterAnimDurationTemp = enterAnim.getDuration();
               enterAnim.setDuration(enterAnimDurationTemp);
               customDialog.getDialogImpl().boxCustom.startAnimation(enterAnim); //通过 getDialogImpl() 获取内部暴露的 boxCustom 元素
               //创建一个背景遮罩层的渐变动画
               ValueAnimator bkgAlpha = ValueAnimator.ofFloat(0f, 1f);
               bkgAlpha.setDuration(enterAnimDurationTemp);
               bkgAlpha.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                   @Override
                   public void onAnimationUpdate(ValueAnimator animation) {
                       //汇报动画进度,同时 animation.getAnimatedValue() 将改变遮罩层的透明度
                       animProgress.run((Float) animation.getAnimatedValue());
                  }
              });
               bkgAlpha.start();
          }
           
           //关闭对话框动画逻辑
           @Override
           public void doExitAnim(CustomDialog customDialog, ObjectRunnable<Float> animProgress) {
               //创建一个资源动画
               int exitAnimResIdTemp = com.kongzue.dialogx.R.anim.anim_dialogx_default_exit;
               Animation exitAnim = AnimationUtils.loadAnimation(me, exitAnimResIdTemp);
               customDialog.getDialogImpl().boxCustom.startAnimation(exitAnim); //通过 getDialogImpl() 获取内部暴露的 boxCustom 元素
               //创建一个背景遮罩层的渐变动画
               ValueAnimator bkgAlpha = ValueAnimator.ofFloat(1f, 0f);
               bkgAlpha.setDuration(exitAnim.getDuration());
               bkgAlpha.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                   @Override
                   public void onAnimationUpdate(ValueAnimator animation) {
                       //汇报动画进度,同时 animation.getAnimatedValue() 将改变遮罩层的透明度
                       animProgress.run((Float) animation.getAnimatedValue());
                  }
              });
               bkgAlpha.start();
          }
      });

对于 animProgress 它本质上是个反向回调执行器,因为动画时长不定,你需要通知 DialogX 当前你的动画到达哪个阶段了,对话框需要根据这个阶段进行操作处理,例如关闭动画执行过程应当是 1f 至 0f 的过程,完毕后应当销毁对话框,那么当 animProgress.run(0f) 时就会执行销毁流程,而启动动画应当是 0f 至 1f 的过程,当 animProgress.run(1f) 时启动对话框的动画完全执行完毕。

另外,你有没有注意到上述代码中的一个小细节?你可以通过 .getDialogImpl() 访问对话框的所有内部实例,这意味着,DialogX 中的所有实例事实上都是对外开放的,你可以在对话框启动后(DialogLifecycle#onShow)通过 DialogImpl 获取对话框的所有内容组件,对他们进行你想做的调整和设置,这都将极大程度上方便开发者对对话框内容进行定制。

正如我一开始所说,DialogX 将坚持努力打造一款更好用,更高效可定制化的对话框组件。

队列对话框

某些场景下需要有“模态”对话框的需要,即,一次性创建多个对话框,组成队列,逐一显示,当上一个对话框关闭时自动启动下一个对话框,此时可以使用队列对话框来完成。

示例代码如下,在 DialogX.showDialogList(...) 中构建多个对话框,请注意这些对话框必须是没有启动的状态,使用 .build() 方法完成构建,以 “,” 分隔组成队列,即可自动启动。

DialogX.showDialogList(
       MessageDialog.build().setTitle("提示").setMessage("这是一组消息对话框队列").setOkButton("开始").setCancelButton("取消")
              .setCancelButton(new OnDialogButtonClickListener<MessageDialog>() {
                   @Override
                   public boolean onClick(MessageDialog dialog, View v) {
                       dialog.cleanDialogList();
                       return false;
                  }
              }),
       PopTip.build().setMessage("每个对话框会依次显示"),
       PopNotification.build().setTitle("通知提示").setMessage("直到上一个对话框消失"),
       InputDialog.build().setTitle("请注意").setMessage("你必须使用 .build() 方法构建,并保证不要自己执行 .show() 方法").setInputText("输入文字").setOkButton("知道了"),
       TipDialog.build().setMessageContent("准备结束...").setTipType(WaitDialog.TYPE.SUCCESS),
       BottomDialog.build().setTitle("结束").setMessage("下滑以结束旅程,祝你编码愉快!").setCustomView(new OnBindView<BottomDialog>(R.layout.layout_custom_dialog) {
           @Override
           public void onBind(BottomDialog dialog, View v) {
               ImageView btnOk;
               btnOk = v.findViewById(R.id.btn_ok);
               btnOk.setOnClickListener(new View.OnClickListener() {
                   @Override
                   public void onClick(View v) {
                                       dialog.dismiss();
                                  }
              });
          }
      })
);

使用过程中,随时可以使用 .cleanDialogList() 来停止接下来的队列对话框的显示。

尾巴

DialogX 正在努力打造一款对开发者更友好,使用起来更为简单方便的对话框组件,若你有好的想法,也欢迎加入进来一起为 DialogX 添砖加瓦,通过 Github 一起让 DialogX 变得更加强大!

DialogX 路牌:github.com/kongzue/Dia…

作者:Kongzue
来源:juejin.cn/post/7197687219581993021

0 个评论

要回复文章请先登录注册