你的位置:【欧冠体育体育手机网页登陆】 > 新品展示 > HarmonyOS 属性动画扩张
HarmonyOS 属性动画扩张
发布日期:2022-08-07 19:01    点击次数:74

想相识更多内容,请拜访:

51CTO和华为平易近间合作共建的鸿蒙技能社区

https://harmonyos.51cto.com

简介

HarmonyOS 供应了AnimatorValue来执行属性动画,然则其编制数很少,并且属性值领域范围于[0,1],也不间接支持动画反转等一些经常使用的操作。在日常开发中,我们常常需求基于这个类举行扩张编写,去适应其实场景。因而,经由过程采集经常使用的场景,摒挡出一个属性动画的扩张类ValueAnimator。

结果演示 HarmonyOS 属性动画扩张-鸿蒙HarmonyOS技能社区 完成思路 1. 动画分类

理论开发进程,我们大部份的动画都是浸染于视图组件。任何宏壮的动画,经由过程逐帧合成,终究均可以或许归结为以下几种根抵动画的组合:

X,Y轴缩放动画 X,Y轴平移动画 通明度动画 转变角度动画 组件宽高尺寸动画 2. 动画操作

关于动画的操作,我们可以或许归结出下列这些措施:

起头动画 平息动画 勾销动画 终止动画 反转动画 配置动画肇端值 配置动画延时 配置动画执行时长 配置动画插值器 配置动画形态监听 配置动画进度监听 配置动画执行次数 配置动画重复情势 配置组件动画属性值 3. 代码完成

3.1 视图动画的完成

体系原生供应的AnimatorValue为我们供应了[0,1]的动画领域。因而最俭朴的完成编制是定义一个ValueAnimator,外部包孕一集体系的AnimatorValue来计算[0,1]的进度值,经由过程自身的逻辑转换为我们期冀的动画值。

public class ValueAnimator {     private AnimatorValue innerAnimator;      // 监听动画值的变换     private final AnimatorValue.ValueUpdateListener valueUpdateListener = new AnimatorValue.ValueUpdateListener() {         @Override         public void onUpdate(AnimatorValue animatorValue, float fraction) {             Object[] takeValues = values;             // 动画反转运算处理惩罚             if (takeReverseLogic && isReversing) {                 takeValues = reverseValues;             }             Object animatedValue = takeValues[0];             // fraction为[0,1]今后时光的进度,经由过程计算转换成理论的动画值             if (animatedValue != null) {                 if (animatedValue instanceof Integer) {                     int start = (int) takeValues[0];                     int end = (int) takeValues[1];                     animatedValue = start + (int) (fraction * (end - start));                 } else {                     float start = (float) takeValues[0];                     float end = (float) takeValues[1];                     animatedValue = start + fraction * (end - start);                 }             }             currentAnimatedValue = animatedValue;             // 将当前进度值看护给外部调用者             if (updateListeners != null) {                 notifyOuterListener(animatorValue, fraction,新品展示 animatedValue);             }             // 假定是组件动画,将动画值转换为视图组件的属性值变换             if (targetHolder != null && targetHolder.get() != null) {                 updateComponentProperty((Float) animatedValue);             }         }     };      // 动画值转换为视图组件的属性变换     private void updateComponentProperty(Float currentValue) {         Component component = targetHolder.get();         for (Property property : targetProperties) {             switch (property) {                 case SCALE_X:// 缩放x                     component.setScaleX(currentValue);                     break;                 case SCALE_Y:// 缩放y                     component.setScaleY(currentValue);                     break;                 case TRANSLATION_X:// 平移x                     component.setTranslationX(currentValue);                     break;                 case TRANSLATION_Y:// 平移y                     component.setTranslationY(currentValue);                     break;                 case ALPHA:// 通明度                     component.setAlpha(currentValue);                     break;                 case ROTATION:// 左右转变                     component.setRotation(currentValue);                     break;                 case WIDTH:// 尺寸宽                     float width = currentValue;                     component.setWidth((int) width);                     break;                 case HEIGHT:// 尺寸高                     float height = currentValue;                     component.setHeight((int) height);                     break;                 default:                     break;             }         }     } 

3.2 反向循环动画的完成

要执行反向循环动画,我们需求监听循环动画的每次循环节点,尔后在下一次动画执行起头把动画的肇端值反置。

private static final int MAX_SIZE = 2;   private final Object[] values = new Object[MAX_SIZE];// 正向动画肇端值   private final Object[] reverseValues = new Object[MAX_SIZE];// 反向动画肇端值    // 配置肇端值时,除了正向动画肇端值,同时构建一份反向肇端值   public void setFloatValues(float start, float end) {       values[0] = start;       values[1] = end;       reverseValues[0] = end;       reverseValues[1] = start;   }    // 监听动画循环点   private final Animator.LoopedListener loopedListener = new Animator.LoopedListener() {       @Override       public void onRepeat(Animator animator) {           // 假定循环情势配置为反向,下次执行为画则反向执行           // 譬如今后是[0,1],动画终止后就会从[1,0]起头执行,再下次又从[0,1],云云循环...           if (takeReverseLogic) {               isReversing = !isReversing;           }           if (listeners != null) {               for (AnimatorListener listener : listeners) {                   listener.onAnimationRepeat(ValueAnimator.this);               }           }       }   };    // 监听动画值的变换   private final AnimatorValue.ValueUpdateListener valueUpdateListener = new AnimatorValue.ValueUpdateListener() {       @Override       public void onUpdate(AnimatorValue animatorValue, float fraction) {           Object[] takeValues = values;           if (takeReverseLogic && isReversing) {               // 痛处循环情势读取正向照旧反向肇端值               takeValues = reverseValues;           }           ...   };    // 反向执行为画   public void reverse() {       takeReverseLogic = !takeReverseLogic;       isReversing = !isReversing;       // 先终止今后动画,尔后再反向执行为画       if (innerAnimator.isRunning()) {           innerAnimator.end();       }       innerAnimator.start();   } 

3.3 动画操作的完成

因为我们焦点的动画值计算是基于原生的ValueAnimator,因而我们根抵的动画操作也是对其执行:

private AnimatorValue innerAnimator;  // 起头动画 public void start() {     if (innerAnimator.getLoopedCount() == AnimatorValue.INFINITE) {         if (repeatMode == RepeatMode.REVERSE) {             takeReverseLogic = true;         }     }     // 对innerAnimator操作     innerAnimator.start(); }      // 终止动画 public void stop() {     // 对innerAnimator操作     innerAnimator.stop(); }  // 勾销动画 public void cancel() {     // 对innerAnimator操作     innerAnimator.cancel(); }  // 别的操作编制声名 ... 
总结

经由过程我们对原生AnimatorValue的扩张,我们完成为了理论开发中大部份应用处景,让理论开发动画的效劳可以或许大大提升。总结一下几点焦点的扩张道理:

视图组件动画完成:监听原活跃画值举行倍率转换,再配置给组件通用属性 反向/循环动画完成:监听循环动画的循环节点,反向赋值下一次动画的肇端值

想相识更多内容,请拜访:

51CTO和华为平易近间合作共建的鸿蒙技能社区

https://harmonyos.51cto.com