Android Path学习笔记

简单说说

<p>
  Path是android中用来封装几何学路径的一个类,因为Path在图形绘制上占的比重还是相当大的,所以经过学习后,对Path中方法进行总结使用与应用

Path类的方法

<p>

图1 Path方法

Path中的方法相对较多,不对期进行一一说明,将平时用的较多的方法拿出来着重说明

1) 将路径连接至某个坐标点

  lineTo(float x, float y)

**(2)改变起始点的位置 **

  moveTo(float x, float y)

(3)闭合路径

  close() 

(4)路径重置

  reset()

(5)画弧形路径

  arcTo(float left, float top, float right, float bottom, RectF oval, float startAngle, float     sweepAngle,boolean forceMoveTo)
  arcTo (RectF oval, float startAngle, float sweepAngle)
  arcTo (RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo)

参数boolean forceMoveTo,当值为true时将会把弧的起点作为Path的起点

(6)**addXXX方法 **直接往Path中添加一些曲线

添加矩形曲线

  addRect(RectF rect,Direction dir)
  addRect(float left, float top, float right, float bottom,Direction dir)

添加椭圆形曲线

  addOval(RectF oval,Direction dir)
  addOval(float left, float top, float right, float bottom,Direction dir)

添加圆形曲线

  addCircle(float x, float y, floatradius,Direction dir)

添加弧形曲线

  addArc(RectF oval, float startAngle, float sweepAngle)
  addArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle)

添加圆角矩形曲线

  addRoundRect(RectF rect, float rx, float ry,Direction dir)
  addRoundRect(float left, float top, float right, float bottom, float rx, float ry,Direction dir)
  addRoundRect(RectF rect, float[] radii,Direction dir)
  addRoundRect(float left, float top, float right, float bottom, float[] radii,Direction dir)

添加path

  addPath(Path src, float dx, float dy)
  addPath(Path src)
  addPath(Path src,Matrix matrix)
而上面这些方法搭配一起就会碰撞出奇妙的火花

<p>
比如

图2 Path绘制图

亦或这个

图3 Path绘制图

还有这个

图4 Path绘制图

好吧我承认这个是我画的,确实比例有问题。。。

也许很多人会觉得利用Path来绘制图像代码量很大而且需要计算的数据也很多,但是我觉得的基本用法还是需要了解也熟练使用的

接下来要介绍的则是Path中的大招,这个方法会带来很多很赞的体验与设计

(7)贝塞尔曲线
<p>
什么是贝塞尔曲线就不做概述了,简单说就是只需要一个起点、一个终点和至少零个控制点则可定义一个贝赛尔曲线
<p>
一阶贝赛尔曲线

图5 一阶贝塞尔曲线公式

其中B(t)为时间为t时点的坐标,P0为起点、Pn为终点,曲线图如下

图6 一阶贝塞尔曲线图

二阶贝塞尔曲线

二阶贝赛尔曲线的一个明显特征是其拥有一个控制点,通过控制点来控制曲线的走向

图7 二阶贝塞尔曲线公式

对应的二阶曲线图如下

图8 二阶贝塞尔曲线图

在Android Path中存在对应的方法来实现二阶贝塞尔曲线

    quadTo(float x1, floaty1, float x2, float y2)  其中x1,y1为控制点,x2,y2为终点

利用好二阶贝塞尔曲线其实可以玩转出一些比较赞的效果了

比如下面的波浪效果

图9 贝塞尔二阶曲线实现的波浪效果

代码实现角度也很简单
<p>

         /* 
         * 设置Path起点 
         * 注意我将Path的起点设置在了控件的外部看不到的区域 
         * 如果我们将起点设置在控件左端x=0的位置会使得贝塞尔曲线变得生硬 
         * 至于为什么刚才我已经说了 
         * 所以我们稍微让起点往“外”走点 
         */  
        mPath.moveTo(-1 / 4F * vWidth, waveY);  
  
        /* 
         * 以二阶曲线的方式通过控制点连接位于控件右边的终点 
         * 终点的位置也是在控件外部 
         * 我们只需不断让ctrX的大小变化即可实现“浪”的效果 
         */  
        mPath.quadTo(ctrX, ctrY, vWidth + 1 / 4F * vWidth, waveY);  
  
        // 围绕控件闭合曲线  
        mPath.lineTo(vWidth + 1 / 4F * vWidth, vHeight);  
        mPath.lineTo(-1 / 4F * vWidth, vHeight);  
        mPath.close();  
  
        canvas.drawPath(mPath, mPaint);  
  
        /* 
         * 当控制点的x坐标大于或等于终点x坐标时更改标识值 
         */  
        if (ctrX >= vWidth + 1 / 4F * vWidth) {  
            isInc = false;  
        }  
        /* 
         * 当控制点的x坐标小于或等于起点x坐标时更改标识值 
         */  
        else if (ctrX <= -1 / 4F * vWidth) {  
            isInc = true;  
        }  
  
        // 根据标识值判断当前的控制点x坐标是该加还是减  
        ctrX = isInc ? ctrX + 20 : ctrX - 20;  
  
        /* 
         * 让“水”不断减少 
         */  
        if (ctrY <= vHeight) {  
            ctrY += 2;  
            waveY += 2;  
        }  
  
        mPath.reset();  
  
        // 重绘  
        invalidate();  

主要通过控制控制点与终点的位置不断的重绘产生波浪的形状

同样的某些下拉刷新的效果也是通过这样的方法去产生的比如

图10 贝塞尔二阶曲线实现的下拉效果

另外QQ“一键下班”功能其实也是基于二阶贝塞尔曲线实现的

图11 QQ一键下班功能

三阶贝塞尔曲线

三阶贝赛尔曲线则是拥有两个控制点,通过控制点来控制曲线的走向

图12 三阶贝塞尔曲线公式

对应的三阶曲线图如下

图13 三阶贝塞尔曲线图

在Android Path中存在对应的方法来实现二阶贝塞尔曲线

  cubicTo(float x1, float y1, float x2, float y2, float x3, float y3)

其中x1,y1为第一个控制点,x2,y2为第二个控制点,x3,y3为终点

利用好三阶贝塞尔曲线其实可以有更多的效果了,在很多的App其实都有运用到了

比如百度贴吧的下拉刷新,美图的下拉刷新,Chrome的下拉刷新,慕课网的下拉刷新,其实都是基于三阶贝塞尔曲线来实现的

简单说下三阶贝塞尔运用的

第一种,和上述的二阶贝塞尔曲线一样,作为波浪使用

<p>
代表例子:慕课App的下拉刷新

图14 慕课App下拉刷新效果

这种实现其实与二阶波浪实现是一致的,控制好两个控制点即可以实现,不做代码的赘述

第二种则是通过闭合的路径产生特殊的效果

<p>
比如说下面这个例子

图15 闭合路径产生的效果

这个效果怎么实现的呢?
<p>
后面给出相关实现的代码

(8)PathMeasure

<p>
PathMeasure其实是测量Path的一个类,通过PathMeasure可以实现一些比较复杂的路径运动效果

 mPathMeasure = new PathMeasure(mPath, true);  
//设置运动的路径点
 mCurrentPosition = new float[2];  
  ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, mPathMeasure.getLength());   
  valueAnimator.setDuration(duration);  
  valueAnimator.addUpdateListener(new AnimatorUpdateListener() {  
  
       @Override  
       public void onAnimationUpdate(ValueAnimator animation) {  
       float value = (Float) animation.getAnimatedValue();  
       // 获取当前点坐标封装到mCurrentPosition  
       mPathMeasure.getPosTan(value, mCurrentPosition, null);  
       postInvalidate();  
    }  
  });  
  valueAnimator.start();    

通过PathMeasure可以实现如下的效果

图16 Path路径运动效果
图17 Path路径运动效果

到此Path中的大部分方法与使用应用都已经描述到了,由于是本人学习笔记,所以大部分的效果图都是来自于网络的分享,感谢各位大牛的分享

Reference

1.自定义控件其实很简单5/12From AigeStudio

2.Android 用Canvas 画几何图形,画出小黄人From 山言两语

3.Android雷达图(蜘蛛网图)绘制 From crazy__chen

4.慕课网app下拉刷新图标填充效果的实现From 安卓弟

5.【Android开源项目解析】QQ“一键下班”功能实现解析From 裸奔的凯子哥

6.四步实现ChromeLikeSwipeLayout效果From 我是Asha

7.三次贝塞尔曲线练习之弹性的圆From shadev

8.Path特效之PathMeasure打造万能路径动效From 学问积年而成

9.【Android开源项目解析】仿支付宝付款成功及"天女散花"效果实现From 裸奔的凯子哥

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,544评论 25 707
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,596评论 4 59
  • 夜深了,星月疲惫地驻守在夜空中,寂静如水。在寂静之下,凡尼尔山脚下的小镇里却是灯火通明,几乎全镇的人都涌向了镇中央...
    陈榟宸阅读 574评论 8 5
  • 赫尔曼·黑塞,德国1877年的70后的老先生,诺贝尔文学奖得主。铁打的诺贝尔,流水的得主。每一个都是让平凡的我们膜...
    小天黑阅读 169评论 0 2
  • 最近看了许多鸡汤,心情类文章,看的时候很惊讶,并不是因为道理多,而是觉得他们对生活的感悟和他们对生活看的那么透彻。...
    邂逅君阅读 424评论 0 1