Android 水波纹显示进度效果,很炫

AndraFolsom 7年前
   <p>关于水波纹的效果想必大家见的已经很多了,我就在这里再啰嗦一次,为了加深自己的印象。先来看看效果图 </p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/69e2c347d2756604de2dbb5f83e3429b.gif"></p>    <p>关于这个效果的实现不必想的太过复杂了,要想实现这个效果,我们还需要了解一下PorterDuff及Xfermode </p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/aa2d0cc894047e98f0a15989a9423b70.jpg"></p>    <p>关于上面的这张图想必大家也见过很多次了。这其实就是PorterDuff的16种模式。效果想比大家已经见到了,下面我们就来一一了解如何使用。 </p>    <p>PorterDuff.Mode.CLEAR (所绘制不会提交到画布上) </p>    <p>PorterDuff.Mode.SRC(显示上层绘制图片) </p>    <p>PorterDuff.Mode.DST(显示下层绘制图片) </p>    <p>PorterDuff.Mode.SRC_OVER(正常绘制显示,上下层绘制叠盖) </p>    <p>PorterDuff.Mode.DST_OVER(上下层都显示。下层居上显示) </p>    <p>PorterDuff.Mode.SRC_IN(取两层绘制交集。显示上层) </p>    <p>PorterDuff.Mode.DST_IN(取两层绘制交集。显示下层) </p>    <p>PorterDuff.Mode.SRC_OUT( 取上层绘制非交集部分) </p>    <p>PorterDuff.Mode.DST_OUT(取下层绘制非交集部分) </p>    <p>PorterDuff.Mode.SRC_ATOP(取下层非交集部分与上层交集部分) </p>    <p>PorterDuff.Mode.DST_ATOP(取上层非交集部分与下层交集部分) </p>    <p>PorterDuff.Mode.XOR( 异或:去除两图层交集部分) </p>    <p>PorterDuff.Mode.DARKEN( 取两图层全部区域,交集部分颜色加深) </p>    <p>PorterDuff.Mode.LIGHTEN(取两图层全部,点亮交集部分颜色) </p>    <p>PorterDuff.Mode.MULTIPLY(取两图层交集部分叠加后颜色) </p>    <p>PorterDuff.Mode.SCREEN( 取两图层全部区域,交集部分变为透明色) </p>    <p>Xfermode有三个子类 : </p>    <p>AvoidXfermode 指定了一个颜色和容差,强制Paint避免在它上面绘图(或者只在它上面绘图)。 </p>    <p>PixelXorXfermode 当覆盖已有的颜色时,应用一个简单的像素异或操作。 </p>    <p>PorterDuffXfermode 这是一个非常强大的转换模式,使用它可以使用图像合成的上图中的任意一种来控制Paint如何与已有的Canvas图像进行交互。要应用转换模式,可以使用setXferMode方法 </p>    <p>paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP)); </p>    <p>这些只能够显示一些合成的效果也就是上面的16种的任意一种效果而已,要想实现水波纹的效果还是不够的,我们还需要借助于贝塞尔曲线来实现水波效果。我们使用到的是Path类的quadTo(x1, y1, x2, y2)方法,属于二阶贝塞尔曲线,使用一张图来展示二阶贝塞尔曲线,这里的(x1,y1)是控制点,(x2,y2)是终止点,起始点默认是Path的起始点(0,0)。关于使用贝塞尔曲线来实现水波效果的原理就是:通过for循环画出两个波纹,我们以WL代表水波纹的长度。需要波纹的-WL点、-3/4*WL点、-1/2*WL、-1/4*WL四个点,通过path的quadTo画出,并无限重复。实现的效果其实也就是我们平时的正弦效果。那么我们也需要了解一下path的使用。</p>    <p>先来看一下效果图 </p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/7c81936111daca0dd09072ec51ceccdd.gif"></p>    <p>实现代码为 <img src="https://simg.open-open.com/show/8db21a436a7b99fd2527de3fcaac0a1f.jpg"></p>    <p><img src="https://simg.open-open.com/show/72fd8e26ccaadfa9f8e59804ea59ae6a.jpg"></p>    <p>先来说一下mPath.moveTo(50, 300);这个方法的作用是将起点移动到屏幕坐标为(50, 300)的位置。mPath.quadTo(assistPoint.x, assistPoint.y, 450, 300);这个方法就是重点了,对应的源码为</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/336f0286eb4677e93234037b9ecff088.png"></p>    <p>第一个坐标是对应的控制点的坐标(assistPoint.x, assistPoint.y),第二个坐标是终点坐标也就是我们看到的水平线的终点位置坐标。上图之所以会出现移动的效果就是因为控制点的位置随着鼠标的位置在移动而产生的。 <br> 下面我们再来看一个效果图 </p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/8e444b9f9a05be1149d1a43dfc00b61f.png"></p>    <p>这个图形的实现代码</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/784915c182b0ab1dc07f634f95b67df0.png"> <img src="https://simg.open-open.com/show/5d9f64ebf8afa2b8435d4bd59b47a485.png"></p>    <p>再来一个效果图以及实现代码 </p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/3a4ec95808120a75e2fe487cbbe05506.png"> <img src="https://simg.open-open.com/show/1e448e8d88bca66c82c1d5edab049898.png"></p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/0a772a9c9294bcfd634cc56ed56d7e8c.png"></p>    <p>上图是我们看到的一个静态的图,但是距离我们实现的效果已经很接近了,实现代码为</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/8336bcb00228bfb6c9ad4f5b1d775901.png"> <img src="https://simg.open-open.com/show/bb20dfbbc87f77c53a53c44beadce091.png"></p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/52899c5bf8d0e2c6301a49b9301f87e8.gif"></p>    <p>这个效果的产生其实就是上面的图形通过for循环产生移动距离产生的,代码如下</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/d0fbba54e2a35b5468f00e998bad4105.png"> <img src="https://simg.open-open.com/show/de82cecfd571ab2d43cebc2a4a5725fb.jpg"></p>    <p>通过对比代码你会发现,其实就是通过移动定时刷新不停的调用onDraw方法,通过distance 的不断变化而产生的动画效果。如果想要实现我们最上面的动画效果还需要借助于PorterDuff及Xfermode,关于PorterDuff及Xfermode上面已经说过了。剩下的就是它们之间的配合使用了 <br> 完整的实现的代码如下: <br> 自定义view</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/c98b26ec131ca265eb7a475db53b30f9.png"> <img src="https://simg.open-open.com/show/f421c16c7c7df71df15e7118aad1f518.jpg"> <img src="https://simg.open-open.com/show/7c82c7b24fdf88b89867b12e147cd753.jpg"> <img src="https://simg.open-open.com/show/564027ee084669334f50af00f0375ec4.png"></p>    <p>MainActivity.class</p>    <p><img src="https://simg.open-open.com/show/08ac7ff9003c47ce529fa1b56f1b9833.png"></p>    <p>布局文件</p>    <p><img src="https://simg.open-open.com/show/f3bb6f6aace2b0f19fb8c18769fd7f21.png"></p>    <h2> </h2>    <p> </p>    <p>来自:http://blog.csdn.net/u014452224/article/details/55193542</p>    <p> </p>