当前位置: 首页 > 科技观察

HarmonyOS属性动画扩展

时间:2023-03-15 21:49:53 科技观察

更多内容请访问:Harmonyos技术社区https://harmonyos.51cto.com,与华为共同建立官方介绍HarmonyOS提供了AnimatorValue来进行属性动画,但是方法数量非常多smallLess,属性取值范围限制在[0,1],不直接支持动画反转等一些常用操作。在日常开发中,我们经常需要基于该类编写扩展以适应实际场景。因此,通过收集常用的场景,整理出一个属性动画的扩展类ValueAnimator。效果演示实现思路1.动画分类在实际的开发过程中,我们大部分的动画都是应用在视图组件上的。任何复杂的动画,逐帧分解,最终可以归纳为以下几种基本动画的组合:X、Y轴缩放动画X、Y轴平移动画透明动画旋转角度动画组件宽高动画2.Animation的动画操作操作,我们可以归纳为以下操作:开始动画暂停动画取消动画结束动画反转动画设置动画起始值设置动画延迟设置动画执行时长设置动画插值器设置动画状态监视器设置动画进度监视器设置动画执行次数设置动画重复模式设置组件动画属性值3.代码实现3.1视图动画的实现系统提供的AnimatorValue为我们提供了[0,1]的动画范围。因此,最简单的实现方式就是定义一个ValueAnimator,其中包含一个系统AnimatorValue来计算[0,1]的进度值,通过自身的逻辑将其转换为我们期望的动画值。publicclassValueAnimator{privateAnimatorValueinnerAnimator;//监听动画值的变化privatefinalAnimatorValue.ValueUpdateListenervalueUpdateListener=newAnimatorValue.ValueUpdateListener(){@OverridepublicvoidonUpdate(AnimatorValueanimatorValue,floatfraction){Object[]takeValues=values;//动画反转运算处理if(takeReverseLogic&&isReversing){takeValues=reverseValues;}ObjectanimatedValue=takeValues[0];//分数为[0,1]当前时间的进度,通过计算转换为实际的动画值if(animatedValue!=null){if(animatedValueinstanceofInteger){intstart=(int)takeValues[0];intend=(int)takeValues[1];animatedValue=start+(int)(fraction*(end-start));}else{floatstart=(float)takeValues[0];floatend=(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);}}};//动画值转换为视图组件的属性变化(当前值);中断;caseSCALE_Y://scaleycomponent.setScaleY(currentValue);break;caseTRANSLATION_X://translatexcomponent.setTranslationX(currentValue);break;caseTRANSLATION_Y://translateycomponent.setTranslationY(currentValue);break;caseALPHA://transparencycomponent.setAlpha(currentValue);break;caseROTATION://中心旋转component.setRotation(currentValue);break;caseWIDTH://sizewidthfloatwidth=currentValue;component.setWidth((int)width);break;caseHEIGHT://sizeheightflotheight=currentValue;component.setHeight((int)height);break;default:break;}}}3.2反向循环动画的实现要进行反向循环动画,我们需要监听循环动画的每个循环节点,然后动画执行开始反转动画的起始值privatestaticfinalintMAX_SIZE=2;privatefinalObject[]values=newObject[MAX_SIZE];//正向动画起始值privatefinalObject[]reverseValues=newObject[MAX_SIZE];//反向动画起始值//设置起始值时,除正向起始值的动画,同时构建一个反向起始值publicvoidsetFloatValues(floatstart,floatend){values[0]=start;values[1]=end;reverseValues[0]=end;reverseValues[1]=start;}//监听动画循环点privatefinalAnimator.LoopedListenerloopedListener=newAnimator.LoopedListener(){@OverridepublicvoidonRepeat(Animatoranimator){//如果循环模式设置为反向,则下一个动画将反向执行//例如,当前是[0,1],动画结束后从[1,0]开始执行,下次从[0,1]开始执行,以此类推...if(takeReverseLogic){isReversing=!isReversing;}if(listeners!=null){for(AnimatorListenerlistener:listeners){listener.onAnimationRepeat(ValueAnimator.this);}}}};//监听动画值变化(AnimatorValueanimatorValuetion,float]Object][fractakeValues=values;if(takeReverseLogic&&isReversing){//根据循环方式读取正向或反向起始值takeValues=reverseValues;}...};//反转动画publicvoidreverse(){takeReverseLogic=!takeReverseLogic;isReversing=!isReversing;//先停止当前动画,再反转动画if(innerAnimator.isRunning()){innerAnimator.end();}innerAnimator.start();}3.3动画操作的实现因为我们核心的动画值计算是基于原生的ValueAnimator,所以我们的基本动画操作也是在它上面进行的:privateAnimatorValueinnerAnimator;//开始动画publicvoidstart(){if(innerAnimator.getLoopedCount()==AnimatorValue.INFINITE){if(repeatMode==RepeatMode.REVERSE){takeReverseLogic=true;}}//运行innerAnimatorinnerAnimator.start();}//停止动画publicvoidstop(){//InnerAnimator操作innerAnimator.stop();}//取消动画publicvoidcancel(){//InnerAnimator操作innerAnimator.cancel();}//其他操作方法声明...通过我们原生的AnimatorValue总结我们有实现了实际开发中的大部分应用场景ment,从而大大提高实际动画开发的效率。总结一些核心扩展原理:View组件动画实现:监听原始动画值进行放大转换,然后设置为普通组件属性reverse/loop动画实现:监听loop动画的loop节点,反向赋起始值下一个动画。欲了解更多信息,请访问:https://harmonyos。51cto.com