高仿 QQ 未讀消息氣泡拖拽黏連效果
今日科技快訊
近日,搜狗CEO王小川在接受采訪時對百度進行了猛批。他認為百度是一家沒有戰略的公司,而且自動駕駛也不是搜索公司該干的事。談及到百度現在最重視的AI,王小川認為搜索本身就是AI,搜索引擎需要像人一樣去思考,來幫用戶選擇出更好的頁面,因此搜狗一直都是在做著AI領域的研究。
正文
了解了Android端的貝塞爾曲線,本篇就舉個栗子練習一下,仿QQ未讀消息氣泡,是最經典的練習貝塞爾曲線的東東,效果如下:

大體思路 就是 :
-
畫兩個圓,一個黏連小球固定在一個點上,一個氣泡小球跟隨手指的滑動改變坐標。隨著兩個圓間距越來越大,黏連小球半徑越來越小。
-
當間距小于一定值,松開手指氣泡小球會恢復原來位置;
-
當間距超過一定值之后,黏連小球消失,氣泡小球繼續跟隨手指移動,此時手指松開,氣泡小球消失~
1. 首先老一套~新建attrs.xml文件,編寫自定義屬性,新建 DragBubbleView 繼承View,重寫構造方法,獲取自定義屬性值,初始化Paint、Path等東東,重寫 onMeasure 計算寬高,這里不再啰嗦~
2. 在 onSizeChanged 方法中確定黏連小球和氣泡小球的圓心坐標,這里我們取寬高的一半:

3. 經分析氣泡小球有以下幾個狀態:默認、拖拽、移動、消失,我們這里定義一下,方便根據不同的狀態分析不同情況:

4. 重寫 onTouchEvent 方法,其中 d 代表兩圓圓心間距, maxD 代表可拖拽的最大間距:

如果控件外面有嵌套 ListView、RecyclerView 等攔截焦點的控件,那就在 ACTION_DOWN 中請求父控件不攔截事件:
getParent().requestDisallowInterceptTouchEvent(true);
然后 ACTION_UP 再把事件還回去:
getParent().requestDisallowInterceptTouchEvent(false);
5. 在 onDraw 方法中畫圓、畫貝賽爾曲線、畫消息個數文本:

其中計算 二階貝塞爾曲線 做需要的起點、終點 和 控制點坐標,順序是 moveTo A, quadTo B, lineTo C, quadTo D, close。先來張示意圖:

手機可點擊放大查看
再上代碼:

6. 氣泡復原的動畫,使用估值器計算坐標


7. 順便來個氣泡狀態的監聽器,方便外部調用監聽其狀態:

8. 關于氣泡爆炸的動畫,思路就是放幾張圖片到 drawable 里,然后動態計數重繪,在 onDraw 中調用 canvas.drawBitmap() 方法,具體如下:

在構造方法中:

然后在手指抬起的時候使用如下動畫:

最后在 onDraw 中:

9. 在布局文件中使用該控件,并使用自定義屬性:

其中 android:clipChildren=” false ” 這個屬性可以使根布局下的子控件超出本身控件范圍的大小,加上這個屬性就可以滿屏幕隨意拖拽而不必拘泥于它本身的大小了,炒雞方便~
還有如果覺得在屬性中設置消息個數不方便,需要在代碼中動態獲取數據并設置的話,只要在 DragBubbleView 中添加一個方法即可
public void setText(String text){
mText = text;
invalidate();
}
10. 在MainActivity中:

總結
這次既練習了自定義View,還囊括了貝賽爾曲線,坐標的計算一定要畫圖,簡單直觀。
來自:http://mp.weixin.qq.com/s/Dvamomoh4OAF2Ipngth2LQ