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

HarmonyOS自定义UI水波纹效果_0

时间:2023-03-12 00:34:43 科技观察

更多内容请访问:Harmonyos技术社区https://harmonyos.51cto.com水波背景动态效果。实现思路生活中随处可见。我们想制作水波纹效果。试想一下,每个人都应该有过往水里扔石头的经历。首先,水波从中心的小圆圈缓缓启动。放大成一个大圆圈,然后慢慢消失。我们只需要在模拟的时候画一个圆,通过Canvas.drawCircle(floatx,floaty,floatradius,Paintpaint);实现方法,根据变化率设置透明度一点点放大半径来实现。效果如下:实现过程:计算view的最大宽度/2作为布局的最大半径,最小半径为0然后给它插值动画让它移动,让它每次画一个圆点击它,圆的半径为(这个.radiusMax*插值动画比例),插值动画比例的曲率是0-1根据比例从小到大计算半径的大小,代码为如下://初始化画笔privatevoidinint(){this.animationRunning=false;this.paint=newPaint();this.paint.setAntiAlias(true);this.paint.setStyle(FILLANDSTROKE_STYLE);this.paint.setColor(newColor(Color.getIntColor("#0000FF")));//设置水波纹的颜色}@OverridepublicvoidonDraw(Componentcomponent,Canvascanvas){floattouchX=(float)this.getWidth()/2;floattouchY=(float)this.getHeight()/2;this.paint.setAlpha(1-1*this.ripplePose);//透明度也是从0到1因为ripplePose是transformedfrom0-1this.radiusMax=component.getWidth()/2;floatradiusMax2=component.getWidth()/4;//根据比例设置半径canvas.drawCircle(touchX,touchY,this.radiusMax*this.ripplePose+radiusMax2,this.paint);}this.ripplePose的变化曲率是0-1根据比例从小到大计算半径画一个圆,为什么我这里加radiusMax2是因为给他一个初始半径,让他不从圆心开始,这样看起来更舒服,点击时触发动画,代码如下:@OverridepublicbooleanonTouchEvent(Componentcomponent,TouchEventtouchEvent){if(touchEvent.getPointerCount()==1&&touchEvent.getAction()==PRIMARY_POINT_DOWN){//手指按下this.downX=this.getTouchX(touchEvent,0);this.createAnimation(this.getTouchX(touchEvent,0),this.getTouchY(touchEvent,0));}elseif(touchEvent.getPointerCount()==1&&touchEvent.getAction()==POINT_MOVE){//一根手指移动}elseif(touchEvent.getPointerCount()==1&&touchEvent.getAction()==PRIMARY_POINT_UP){//一根手指抬起this.invalidate();}returnfalse;}效果如下:但是当我用ListContainer给PageSlider应用水波纹的时候,滑动的时候也会触发水波纹,所以需要事件冲突解决后加入长按阴影效果,listContainer的子item在PageSlider页面滑动时也会触发click事件,导致各种事件冲突。解决办法是在Touch事件中计算定义各种事件,一个一个打断。1.点击事件:抬起时间-按下时间不超过200ms2。长按事件:按下超过200ms3。长按滑动事件:手机监视器中计算出的滑动距离超过20,时间超过200,没有抬起4.短按滑动事件:时间小于200ms,距离大于200px,没有抬起5.然后处理各种事件。另外发现点击手机会触发mobile事件,但是模拟器不会触发。这也需要注意!这样就完成了整个绘制过程,代码如下:/***触摸监听**@paramcomponentview*@paramtouchEventtouchEvent*@return是否消费*/publicbooleanonTouchEvent(Componentcomponent,TouchEventtouchEvent){if(touchEvent.getPointerCount()==NUM1&&touchEvent.getAction()==NUM1){this.downX=this.getTouchX(touchEvent,0);this.downY=this.getTouchY(touchEvent,0);this.downTime=System.currentTimeMillis();this.isDownPose=true;this.isSlide=false;isYinYing=false;}elseif(touchEvent.getPointerCount()==NUM1&&touchEvent.getAction()==NUM3){floatupx=this.getTouchX(touchEvent,0);longtheTime=System.currentTimeMillis();intxjuli=(int)Math.abs(upx-downX);inttimejuli=(int)Math.abs(theTime-this.downTime);if(isDownPose&&timejuli>NUM200&&xjuliNUM250){this.invalidate();}else{this.isDownPose=false;}this.isDownPose=false;}returntrue;}/***长按监听**@paramcomponentview*/@OverridepublicvoidonLongClicked(Componentcomponent){this.createAnimation(this.downX,this.downY);myevenHandler.sendEvent(1,NUM250);this.isSlide=true;}/***绘图制作**@paramvar1Component*@paramvar2Canvas*/publicvoidonDraw(Componentvar1,Canvasvar2){if(isYinYing){this.paint.setAlpha(NUM03F);var2.drawCircle(this.touchX,this.touchY,this.radiusMax*this.ripplePose-0/NUM2F,this.paint);}else{if(this.getWidth()!=0&&this.getHeight()!=0){this.radiusMax=(float)Math.sqrt(this.getWidth()*this.getWidth()+this.getHeight()*this.getHeight());if(this.rippleType!=NUM2){this.radiusMax/=NUM2F;}this.radiusMax-=(float)this.ripplePadding;if(this.isCentered||this.rippleType==1){this.touchX=(float)this.getWidth()/NUM2F;this.touchY=(float)this.getHeight()/NUM2F;}this.paint.setAlpha(this.rippleAlpha-this.rippleAlpha*this.ripplePose);floatvar3=0.0F;if(this.rippleType==NUM1&&this.ripplePose>NUM04){this.paint.setStyle(Paint.Style.STROKE_STYLE);var3=this.radiusMax*this.ripplePose-this.radiusMax*(this.ripplePose-NUM04)/NUM06;this.paint.setStrokeWidth(this.radiusMax*this.ripplePose-this.radiusMax*(this.ripplePose-NUM04)/NUM06);}else{this.paint.setStyle(Paint.Style.FILL_STYLE);}var2.drawCircle(this.touchX),这个.touchY,这个.radiusMax*this.ripplePose-var3/NUM2F,this.paint);}}}效果如下:完整项目代码更多信息请访问:https://harmonyos.51cto.com