EasyDialog 简介 :
-- 作用 : 用于在界面进行一些介绍, 说明;
-- 效果图 :
一. EasyDialog 源码解析
1. 实现原理
实现原理 :
-- EasyDialog 效果 : 在点击后, 会从屏幕外飞入对话框, 飞入恰好能够正好处于特定 View 组件的上方 或者下方;
-- 本质 : 点击按钮弹出的对话框会填充整个屏幕, 背景设置成透明的, 然后会计算组件坐标, 记录坐标位置, 再在弹出的整个对话框中 绘制一个 带小三角对话框的布局, 并让其执行动画;
2. 动画效果总结
(1) 动画实现核心代码
对话框显示小时动画效果实现代码片段 :
private AnimatorSet animatorSetForDialogShow; private AnimatorSet animatorSetForDialogDismiss; private List<Animator> objectAnimatorsForDialogShow; private List<Animator> objectAnimatorsForDialogDismiss; /** * 对话框显示的动画 */ private void onDialogShowing() { if (animatorSetForDialogShow != null && objectAnimatorsForDialogShow != null && objectAnimatorsForDialogShow.size() > 0) { animatorSetForDialogShow.playTogether(objectAnimatorsForDialogShow); animatorSetForDialogShow.start(); } } /** * 对话框消失的动画 */ private void onDialogDismiss() { if (animatorSetForDialogDismiss.isRunning()) { return; } if (animatorSetForDialogDismiss != null && objectAnimatorsForDialogDismiss != null && objectAnimatorsForDialogDismiss.size() > 0) { animatorSetForDialogDismiss .playTogether(objectAnimatorsForDialogDismiss); animatorSetForDialogDismiss.start(); animatorSetForDialogDismiss .addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { dialog.dismiss(); } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } }); } else { dialog.dismiss(); } }
(2) AnimatorSet 简介
AnimationSet 与 AnimatorSet 区别 : AnimatorSet 功能较强;
-- AnimatorSet : 执行的是 Animator 动画, 主要是靠改变视图属性产生动画效果;
-- AnimationSet : 执行的是 Animation 动画, 主要是靠改变视图的外观实现动画效果;
Animator 简介 : Animator 也是一种动画, 可以由用户执行开始, 中断执行, 还可以设置动画执行监听器;
AnimatorSet 简介 :
-- 功能 : 按照特定顺序执行一个 Animator 动画集合, 动画可以一起执行, 先后执行, 延迟执行;
-- 添加动画 : 有两种方式向 AnimatorSet 中添加动画, 调用 playTogether() 或者 playSequentially() 可以一次性向其中添加一个 动画集合, 调用 AnimatorSet.Builder 中得 play() 方法, 可以一个一个地向其中添加动画;
3. 坐标计算时机
坐标计算 : 计算坐标时需要获取组件的宽 和 高, 下面的代码中可以获取宽高, 获取到宽高后, 其坐标自然就计算好了;
-- 获取屏幕宽高代码 : 在其中的 onGlobalLayout 方法中可以获取其宽高;
/* * 获取对话框的宽 高 * 不是真的获取对话框的宽高, 是在对话框被构建绘制到 布局中时 * 利用这个时机去设置对话框位置 */ ViewTreeObserver viewTreeObserver = dialogView.getViewTreeObserver(); viewTreeObserver .addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { // 当View可以获取宽高的时候,设置view的位置 relocation(location); } });