Android高亮引导页的简单实现

       前段时间公司APP有需求做一个内部的高亮引导页,我之所以说内部,因为外部也有引导页(这不是废话嘛,-_-||)。具体的样式想必大家都很清楚,就是那种在某个页面上进行操作指引的那种效果。本文着重说了内部引导页,是为了区别于外部引导页,外部引导页就是那种启动app时进行左右滑动引导的页面。虽然我知道网上这种框架肯定一大堆,但是再好的框架也比不了自己的思考以及实现。别人的永远是别人的东西,在去看别人的成熟框架之前,自己动手做一个看看,看能不能凭着自己的现有知识去实现它。

       好了,废话不多说,开始我们的思考。页面的指引从外表上看有如下几个特点:1.全屏透明灰色层,只有某块区域发亮。2.发亮区域的形状可以是矩形,圆角矩形,椭圆等等,并且周边附带说明文字。3.点击屏幕可以进行下一步指引,也就是切换下一个发亮区域,指引完毕后灰色层消失,界面正常显示。好了,基本效果就这些了,至于更加炫酷的效果不在本文的讨论范围之内。下面,我们将一步一步去实现。

一.全屏透明灰色层

       对于全屏透明灰色层的实现,我的第一反应就是原界面上覆盖了一层透明的灰色界面。OK,既然是覆盖,那么咱们就可以自定义一个view,颜色是灰色透明的,在onDraw方法里写上canvas.drawColor(bgColor)就行了,bgColor就是灰色透明色的argb值。OK,灰色透明层就好了。这么快就好了?是的,但是还要将它覆盖在原有界面之上啊。没错,我们知道,我们的页面中的根view叫decorView,里面有个contentView就是我们在Activity中调用setContentView()所设置的view。OK,思路来了,我们只要将用户设置的layout和我们自定义的灰色层共同加入到contentView里面,并且保证我们的灰色层在上面就行了。说做就做,看代码:

代码中的content就是contentView,首先获取到用户自己设置的view,然后将view和我们的view共同加入到RelativeLayout里面,并且设置为match_parent,最后再将relativeLayout加入到contentView里面就好了。

二.部分区域高亮

       部分区域高亮的效果无非就是两点,一是高亮区域没有被灰色层覆盖,即将灰色层的这一块“抠”出来,透明显示;二是高亮屏幕,使得高亮区域和其他地方亮度有着明显差距就行。OK,如何使灰色层不覆盖高亮区域呢?这就要用到图像混合模式了,即PorterDuffXfermode,将其混合模式设置为android.graphics.PorterDuff.Mode.CLEAR就行了,此外还要关闭硬件加速等等。关于这一块的知识我就不详细介绍了,有兴趣的同学可以自己研究下。好的,那么高亮屏幕呢?那就更简单了:

亮度值最大是255,改变light值就好了。

三.高亮区域的形状

       高亮区域的形状我这里写了三种,有矩形,圆角矩形以及椭圆。在设置完图像混合模式之后,我们可以canvas来画出对应的形状,代码如下:

如图所示,矩形和圆角矩形canvas都有现成的函数,只要传入高亮区域的矩形数值就行,至于椭圆嘛,也有,不过传入的矩形是椭圆的外接矩形,也就是说直接调用drawOval画出来的椭圆会小于高亮区域,那怎么办呢?那就根据高亮区域矩形算出矩形的外接椭圆咯。设高亮区域矩形的长宽的一半分别为a,b,那么该矩形的内切椭圆公式为:

                                                                                     x^2/a^2+y^2/b^2=1

而椭圆的一般公式我们可以写为:

                                                                                      x^2/a^2+y^2/b^2=t

我们将椭圆放大,使得椭圆经过点(a,b),那么该椭圆就是高亮矩形的外接椭圆了,代入上述公式得t=2,等式右边归一处理,有

                                                                              x^2/(\sqrt{2a})^2+y^2/(\sqrt{2b})^2=1

也就是说,高亮矩形的外接椭圆的外接矩形,暂且称为大矩形,大矩形的长宽是高亮矩形的\sqrt{2}倍,至此,大矩形数值也出来了,代入到drawOval中画出来的就是高亮矩形的外接椭圆了,也就是代码中的rectF2,代码里面的小数就是根据\sqrt{2}取1.414得来的,具体细则一看便知。

四.提示文字、曲线、虚线框

       关于提示文字的位置,我的想法比较简单,高亮区域在上,文字在下;区域在左,文字在右,以此类推。因此,只要知道高亮区域的坐标,就可以知道文字的大概位置。说了这么多,大家还不知道高亮区域的位置是怎么确定的。其实根据用户传入的view就可以了,view.getLocationOnScreen(xy)可以将view的左上角坐标获取到数组xy中,再通过view.getWidth()和getHeight()就可以确定高亮的区域范围了。好了,上图:

代码注释写的很清楚,根据高亮区域在屏幕中的上下左右来确定文字的上下左右,图中只是部分代码,没什么难理解的地方,因此不再赘述。

       至于连接高亮区域和文字的曲线,这里根据区域的位置,确定曲线起点为区域的上边缘中点或者下边缘中点,曲线终点为文字的位置,主要都是逻辑代码,不再赘述。

       虚线框和高亮区域的形状保持一致,通过path和pathEffect进行绘制,代码如下:

 代码注释很清楚,通过path绘制形状,pathEffect指定虚线形状、弧度形状或者两者综合。

五.点击屏幕切换高亮区域

       点击展示下一个高亮区域,无非就是替换代码里面的高亮view,绘制过程完全一样。

六.其他注意点

       最主要的知识点无非就是用户view的绘制周期,如果用户在onCreate函数里面直接调用我们的自定义View,那么就会出现view获取不到宽高的情况,因此,我们可以通过如下方式进行回调:

通过getViewTreeObserver可以在view绘制完成使进行监听,从而获取到view的宽高和坐标等信息。

七.使用方法

       本文的代码已上传至我的GitHub,地址https://github.com/HarrisonChe/InnerGuideViewLibrary。使用方法详见上述GitHub。

本文的运行结果如下图所示:

       那么,到这里,本文就全部结束了,其实仔细看来,用到的知识点也没有很多很复杂,只是更多的是细节的处理和优化。我一直都觉得,自己动手实现才会最快的学习之路,虽然本文的实现与网上成熟的框架还有着不小的差距,但是自己去思考去实现才会有体会,有体会才有会改进的动力,因此有什么不到之处,欢迎大家留言评论!

发布了10 篇原创文章 · 获赞 89 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/cbzcbzcbzcbz/article/details/82503131