前言
扯來(lái)扯去湖员,前面三篇自定義 View 文章械拍,終于扯完了一些知識(shí)點(diǎn),有些枯燥如庭,所以我也是講下核心點(diǎn)碰煌,沒(méi)有細(xì)分析,主要是讓各位有點(diǎn)印象和了解绅作。這篇終于是實(shí)踐芦圾,敲代碼的了,因?yàn)楣ぷ髟蚨砣希@篇拖的比較久个少,不過(guò)這系列會(huì)一直更新下去的,會(huì)把我工作中用到的自定義 View 也會(huì)加上去眯杏。好了夜焦,回歸正原題,說(shuō)到自定義 View 岂贩,似乎都離不開(kāi)貝塞爾曲線茫经,因此,第一篇實(shí)踐就是與貝塞爾曲線有關(guān)的。
目錄
從0到1Android自定義View(四) 貝塞爾曲線.png
一卸伞、貝塞爾曲線
1抹镊、貝塞爾曲線簡(jiǎn)介
來(lái)看看官方對(duì)神奇的賽貝爾曲線的介紹:貝塞爾曲線于 1962,由法國(guó)工程師皮埃爾·貝塞爾所廣泛發(fā)表荤傲,他運(yùn)用貝塞爾曲線來(lái)為汽車的主體進(jìn)行設(shè)計(jì)垮耳。貝塞爾曲線最初由 Paul de Casteljau 于 1959 年運(yùn)用 de Casteljau 演算法開(kāi)發(fā),以穩(wěn)定數(shù)值的方法求出貝茲曲線遂黍。貝塞爾曲線主要用于二維圖形應(yīng)用程序中的數(shù)學(xué)曲線终佛,曲線由起始點(diǎn),終止點(diǎn)(也稱錨點(diǎn))和控制點(diǎn)組成雾家,通過(guò)調(diào)整控制點(diǎn)铃彰,貝塞爾曲線的形狀會(huì)發(fā)生變化。
看完后是不是一臉蒙蔽榜贴,一句話理解貝塞爾曲線就是:將任意一條曲線轉(zhuǎn)化為精確的數(shù)學(xué)公式豌研。
2、賽貝爾曲線公式
竟然說(shuō)了是將曲線轉(zhuǎn)化為精確的數(shù)學(xué)公式唬党,那么我們來(lái)看下具體的數(shù)學(xué)公式( 注:以下公式中鹃共,B(t) 為 t 時(shí)間下點(diǎn)的坐標(biāo); P0 為起點(diǎn),Pn 為終點(diǎn),Pi 為控制點(diǎn) ):
(1) 一階貝塞爾曲線(線段)
由 P0 至 P1 的連續(xù)點(diǎn)驶拱, 描述的一條線段
一階貝塞爾曲線公式.jpg
一階貝塞爾曲線公式圖.jpg
(2) 二階貝塞爾曲線(拋物線):
由 P0 至 P1 的連續(xù)點(diǎn) Q0霜浴,描述一條線段。
由 P1 至 P2 的連續(xù)點(diǎn) Q1蓝纲,描述一條線段阴孟。
由 Q0 至 Q1 的連續(xù)點(diǎn) B(t),描述一條二次貝塞爾曲線税迷。
二階貝塞爾曲線(拋物線)公式.jpg
二階貝塞爾曲線(拋物線)公式圖.jpg
(3) 三階貝塞爾曲線:
三階貝塞爾曲線公式.jpg
三階貝塞爾曲線公式圖.jpg
3永丝、貝塞爾曲線在 Android 中的應(yīng)用
其實(shí)貝塞爾曲線在 Android 自定義 View 中運(yùn)用還是挺多的,比如
Android 5.0 后下拉刷新的陰影曲線
QQ 消息提醒的小紅點(diǎn)
用于左右滑動(dòng)時(shí)顯示個(gè)數(shù)的點(diǎn)的移動(dòng)動(dòng)畫
水流波動(dòng)效果
一個(gè)彈性效果的抽屜菜單
4箭养、Android Path 類中提供貝塞爾曲線的操作方法
在 Android 開(kāi)發(fā)中慕嚷,要實(shí)現(xiàn)貝塞爾曲線其實(shí)還是很簡(jiǎn)單的,因?yàn)?Android 已經(jīng)給我們提供了相關(guān)接口毕泌,此接口方法在 Path 類中喝检,而關(guān)于 Path 類的講解,前面一篇博客就介紹過(guò)了撼泛。而且通過(guò) Android 的 API 可以知道挠说,貝塞爾曲線從 API1 就開(kāi)始支持了。下面就是賽貝爾曲線對(duì)應(yīng)的 API 方法了愿题。
貝塞爾曲線對(duì)應(yīng)的方法演示動(dòng)畫
一階曲線
(線性曲線)lineTo
一階貝塞爾曲線動(dòng)圖.gif
二階曲線quadTo
二階貝塞爾曲線(拋物線)動(dòng)圖.gif
三階曲線cubicTo
三階貝塞爾曲線動(dòng)圖.gif
四階曲線無(wú)
四階貝塞爾曲線動(dòng)圖.gif
5损俭、通過(guò) de Casteljau 算法繪制貝塞爾曲線
上面提過(guò)蛙奖,Path 類中提供了畫一到三階的貝塞爾曲線的方法,如果我們需要繪制更高階的貝塞爾曲線呢撩炊?我們可以采用德卡斯特里奧算法(De Casteljau’s Algorithm)來(lái)實(shí)現(xiàn)貝塞爾曲線外永。
效果圖:
貝塞爾曲線截屏1.gif
貝塞爾曲線截屏2.gif
貝塞爾曲線截屏3.gif
貝塞爾曲線截屏4.gif
Github 上的代碼:beziercurve
里面主要就一個(gè)類,beziercurve拧咳,這是個(gè)自定義 View 伯顶,BezierCurve里面主要提供了以下的方法:
Methods:
method 方法description 描述
voidstart()開(kāi)始貝塞爾曲線(required)
voidstop()停止貝塞爾曲線(optional)
booleanaddPoint()增加控制點(diǎn)(optional)
booleandelPoint()刪除控制點(diǎn)(optional)
intgetOrder()獲取貝塞爾曲線階數(shù)(optional)
voidsetRate(int rate)設(shè)置移動(dòng)速率(optional)
voidsetTangent(boolean tangent)設(shè)置是否顯示切線(optional)
voidsetLoop(boolean loop)設(shè)置是否循環(huán)(optional)
voidsetOrder(int order)設(shè)置貝塞爾曲線階數(shù)(optional)
最后通過(guò)BezierCurveActivity來(lái)展示。
二骆膝、貝塞爾曲線的應(yīng)用
1.QQ 消息提醒可拖拽紅點(diǎn)
Github 上的項(xiàng)目地址:qqmsgnotify
效果圖:
QQ消息提醒紅點(diǎn).gif
主要是在繪制紅點(diǎn)的時(shí)候運(yùn)用了貝塞爾曲線祭衩,在固定的位置中,拖拽的時(shí)候阅签,有一種粘性的效果掐暮,就是這里運(yùn)用了貝塞爾曲線。
QQ消息提醒紅點(diǎn).png
運(yùn)用:
(1) 在對(duì)應(yīng)的位置創(chuàng)建一個(gè) TextView
(2) 設(shè)置 GooViewListener 監(jiān)聽(tīng)事件就可以了
mTvPoint = (TextView) findViewById(R.id.point_conversation);? ? ? ? mTvPoint.setText("10");? ? ? ? mTvPoint.setTag(10);? ? ? ? GooViewListener listener =newGooViewListener(this, mTvPoint) {@OverridepublicvoidonDisappear(PointF mDragCenter){super.onDisappear(mDragCenter);? ? ? ? ? ? ? ? Toast.makeText(QQMsgNotifyActivity.this,"消失了", Toast.LENGTH_SHORT).show();? ? ? ? ? ? }@OverridepublicvoidonReset(booleanisOutOfRange){super.onReset(isOutOfRange);? ? ? ? ? ? ? ? Toast.makeText(QQMsgNotifyActivity.this,"重置了", Toast.LENGTH_SHORT).show();? ? ? ? ? ? }? ? ? ? };? ? ? ? mTvPoint.setOnTouchListener(listener);
2.Viewpage頁(yè)面引導(dǎo)切換動(dòng)畫
Github 上的項(xiàng)目地址:guideview
效果圖:
ViewPage引導(dǎo)動(dòng)畫.gif
)
其實(shí)這個(gè)例子也是政钟,運(yùn)用貝塞爾曲線也就是在繪制那個(gè)圓形的地方而已路克,其他地方基本不怎么使用貝塞爾曲線。