Android如何实现流光和光影移动效果

Android如何实现流光和光影移动效果

这篇文章将为大家详细讲解有关Android如何实现流光和光影移动效果,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

概述:

开发过程中,看到有些界面用到一道光线在屏幕中掠过的效果,觉得挺炫的。所以查找相关资料自己实现了一遍。

先上个预览图:

实现思路:

简单来说就是在一个view中绘制好一道光影,并不断改变光影在view中的位置。

1.首先我们先了解一下光影怎么绘制

在了解如何绘制之前,我们先看一下LinearGradient的构造方法

/***Createashaderthatdrawsalineargradientalongaline.**@paramx0Thex-coordinateforthestartofthegradientline*@paramy0They-coordinateforthestartofthegradientline*@paramx1Thex-coordinatefortheendofthegradientline*@paramy1They-coordinatefortheendofthegradientline*@paramcolorsThesRGBcolorstobedistributedalongthegradientline*@parampositionsMaybenull.Therelativepositions[0..1]of*eachcorrespondingcolorinthecolorsarray.Ifthisisnull,*thethecolorsaredistributedevenlyalongthegradientline.*@paramtileTheShadertilingmode***翻译过来:*x0,y0为渐变起点,x1,y1为渐变的终点**colors数组为两点间的渐变颜色值,positions数组取值范围是0~1*传入的colors[]长度和positions[]长度必须相等,一一对应关系,否则报错*position传入null则代表colors均衡分布**tile有三种模式*Shader.TileMode.CLAMP:边缘拉伸模式,它会拉伸边缘的一个像素来填充其他区域*Shader.TileMode.MIRROR:镜像模式,通过镜像变化来填充其他区域*Shader.TileMode.REPEAT:重复模式,通过复制来填充其他区域*/LinearGradient(floatx0,floaty0,floatx1,floaty1,@NonNull@ColorIntint[]colors,@Nullablefloat[]positions,@NonNullTileModetile)

colors[]和positions[]的说明结合下图,这样理解起来应该就比较明朗了

回到正题,如何绘制光影。我们看到的那道光可以参照下图:

根据分析得到我们的着色器是线性着色器(其他着色器请查询相关api):

LinearGradient(a的x坐标,a的y坐标,c的x坐标,c的y坐标,newint[]{Color.parseColor("#00FFFFFF"),Color.parseColor("#FFFFFFFF"),Color.parseColor("#00FFFFFF")},newfloat[]{0f,0.5f,1f},Shader.TileMode.CLAMP)

2.给画笔上色。设置着色器mPaint.setShader(mLinearGradient)

3.给定一个数值范围利用数值生成器ValueAnimator产生数值,监听数值变化。每次回调都将该数值传入光影的起点和终点并进行绘制

代码如下:

/***author:caoyb*createdon:2021/12/2015:13*description:*/publicclassConfigLoadingViewextendsView{privatePaintmPaint;privatePathmPath;privateLinearGradientmLinearGradient;privateValueAnimatormValueAnimator;publicConfigLoadingView(Contextcontext){this(context,null);}publicConfigLoadingView(Contextcontext,@NullableAttributeSetattrs){this(context,attrs,0);}publicConfigLoadingView(Contextcontext,@NullableAttributeSetattrs,intdefStyleAttr){super(context,attrs,defStyleAttr);init();}privatevoidinit(){mPaint=newPaint();mPath=newPath();}privatevoidinitPointAndAnimator(intw,inth){Pointpoint1=newPoint(0,0);Pointpoint2=newPoint(w,0);Pointpoint3=newPoint(w,h);Pointpoint4=newPoint(0,h);mPath.moveTo(point1.x,point1.y);mPath.lineTo(point2.x,point2.y);mPath.lineTo(point3.x,point3.y);mPath.lineTo(point4.x,point4.y);mPath.close();//斜率kfloatk=1f*h/w;//偏移floatoffset=1f*w/2;//0f-offset*2为数值左边界(屏幕外左侧),w+offset*2为数值右边界(屏幕外右侧)//目的是使光影走完一遍,加一些时间缓冲,不至于每次光影移动的间隔都那么急促mValueAnimator=ValueAnimator.ofFloat(0f-offset*2,w+offset*2);mValueAnimator.setRepeatCount(-1);mValueAnimator.setInterpolator(newLinearInterpolator());mValueAnimator.setDuration(1500);mValueAnimator.addUpdateListener(newValueAnimator.AnimatorUpdateListener(){@OverridepublicvoidonAnimationUpdate(ValueAnimatoranimation){floatvalue=(float)animation.getAnimatedValue();mLinearGradient=newLinearGradient(value,k*value,value+offset,k*(value+offset),newint[]{Color.parseColor("#00FFFFFF"),Color.parseColor("#1AFFFFFF"),Color.parseColor("#00FFFFFF")},null,Shader.TileMode.CLAMP);mPaint.setShader(mLinearGradient);invalidate();}});mValueAnimator.start();}@OverrideprotectedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec){super.onMeasure(widthMeasureSpec,heightMeasureSpec);intwidthSize=MeasureSpec.getSize(widthMeasureSpec);intheightSize=MeasureSpec.getSize(heightMeasureSpec);initPointAndAnimator(widthSize,heightSize);}@OverrideprotectedvoidonDraw(Canvascanvas){super.onDraw(canvas);canvas.drawPath(mPath,mPaint);}@OverrideprotectedvoidonDetachedFromWindow(){super.onDetachedFromWindow();mValueAnimator.cancel();}}

注意点:

LinearGradient里参数之一:
color[]参数只能是16进制的RGB数值,不能传R.color.xxx。R.color.xxx虽然是int型,但拿到的是资源ID,并不是16进制RGB

关于“Android如何实现流光和光影移动效果”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

发布于 2021-12-22 21:56:11
收藏
分享
海报
0 条评论
55
上一篇:mysql怎么实现最大连接数 下一篇:如何使用docker部署grafana+prometheus配置
目录

    推荐阅读

    0 条评论

    本站已关闭游客评论,请登录或者注册后再评论吧~

    忘记密码?

    图形验证码