作者簡介 原創(chuàng)微信公眾號郭霖 WeChat ID: guolin_blog
本篇來自猴菇先生的投稿,分享了一個貝賽爾曲線的應(yīng)用凤巨,希望能對大家有所幫助。
猴菇先生的博客地址:
http://blog.csdn.net/qq_31715429
正文
了解了Android端的貝塞爾曲線,本篇就舉個栗子練習(xí)一下骂铁,仿QQ未讀消息氣泡票从,是最經(jīng)典的練習(xí)貝塞爾曲線的東東漫雕,效果如下:
大體思路就是:
畫兩個圓滨嘱,一個黏連小球固定在一個點(diǎn)上,一個氣泡小球跟隨手指的滑動改變坐標(biāo)浸间。隨著兩個圓間距越來越大太雨,黏連小球半徑越來越小。
當(dāng)間距小于一定值魁蒜,松開手指氣泡小球會恢復(fù)原來位置囊扳;
當(dāng)間距超過一定值之后,黏連小球消失兜看,氣泡小球繼續(xù)跟隨手指移動锥咸,此時手指松開,氣泡小球消失~
1.首先老一套~新建attrs.xml文件细移,編寫自定義屬性搏予,新建 DragBubbleView 繼承View,重寫構(gòu)造方法弧轧,獲取自定義屬性值雪侥,初始化Paint、Path等東東精绎,重寫 onMeasure 計算寬高速缨,這里不再啰嗦~
2.在 onSizeChanged 方法中確定黏連小球和氣泡小球的圓心坐標(biāo),這里我們?nèi)捀叩囊话耄?/p>
3.經(jīng)分析氣泡小球有以下幾個狀態(tài):默認(rèn)代乃、拖拽旬牲、移動、消失襟己,我們這里定義一下引谜,方便根據(jù)不同的狀態(tài)分析不同情況:
4.重寫 onTouchEvent 方法,其中d代表兩圓圓心間距擎浴,maxD代表可拖拽的最大間距:
如果控件外面有嵌套 ListView员咽、RecyclerView 等攔截焦點(diǎn)的控件,那就在 ACTION_DOWN 中請求父控件不攔截事件:
getParent().requestDisallowInterceptTouchEvent(true);
然后?ACTION_UP 再把事件還回去:
getParent().requestDisallowInterceptTouchEvent(false);
5.在 onDraw 方法中畫圓贮预、畫貝賽爾曲線贝室、畫消息個數(shù)文本:
其中計算 二階貝塞爾曲線 做需要的起點(diǎn)、終點(diǎn) 和 控制點(diǎn)坐標(biāo)仿吞,順序是 moveTo A, quadTo B, lineTo C, quadTo D, close滑频。先來張示意圖:
手機(jī)可點(diǎn)擊放大查看
再上代碼:
6.氣泡復(fù)原的動畫,使用估值器計算坐標(biāo)
7.順便來個氣泡狀態(tài)的監(jiān)聽器唤冈,方便外部調(diào)用監(jiān)聽其狀態(tài):
8.關(guān)于氣泡爆炸的動畫峡迷,思路就是放幾張圖片到 drawable 里,然后動態(tài)計數(shù)重繪,在 onDraw 中調(diào)用 canvas.drawBitmap() 方法绘搞,具體如下:
在構(gòu)造方法中:
然后在手指抬起的時候使用如下動畫:
最后在 onDraw 中:
9.在布局文件中使用該控件彤避,并使用自定義屬性:
其中android:clipChildren=”false”這個屬性可以使根布局下的子控件超出本身控件范圍的大小,加上這個屬性就可以滿屏幕隨意拖拽而不必拘泥于它本身的大小了夯辖,炒雞方便~
還有如果覺得在屬性中設(shè)置消息個數(shù)不方便琉预,需要在代碼中動態(tài)獲取數(shù)據(jù)并設(shè)置的話,只要在 DragBubbleView 中添加一個方法即可
publicvoidsetText(Stringtext){ ? ?mText=text; ? ?invalidate();}
10.在MainActivity中:
總結(jié)
這次既練習(xí)了自定義View蒿褂,還囊括了貝賽爾曲線圆米,坐標(biāo)的計算一定要畫圖,簡單直觀啄栓。
項(xiàng)目地址:
https://github.com/MonkeyMushroom/DragBubbleView
完娄帖。。谴供。块茁。齿坷。桂肌。。永淌。崎场。。遂蛀。谭跨。。李滴。螃宙。。所坯。谆扎。。芹助。堂湖。
文章原創(chuàng)作者GuoLin 書籍推薦
郭林大神原創(chuàng)android 書籍:《第一行代碼 android》