Android自定義View之——QQ紅點取消控件

最近需要做一個類似QQ小紅點的拖拽控件,一搜還是有挺多的,但大部分是復制粘貼,要么直接貼代碼,要么思路上文不接下文,或多或少有些問題,想著也不是很復雜,與其花時間去改他人的代碼,還不如自己擼一個,就參照著網絡上大概的思路也做了一個出來,進行了優化并且簡單封裝成了 demo StickyDot

先看下效果圖:ps:效果一般,請見諒

最終效果

** 考慮場景**

依附在列表Item內(qq聊天);
依附于界面上(類似于360 懸浮小機器人);

以上場景有幾個特點:

位置是不確定的,可以在屏幕的任何地方;
隨時出現,隨時隱藏(與ofo小黃車一樣,即停即走、用完即走)。
能捕獲觸摸事件,層級要在最上層;

選擇 懸浮 技術 :

1、將其放置在 Activity 的根 View下
(ViewGroup) view.getRootView().findViewById(android.R.id.content)
2、放置在窗體內,使用WindowManager。

以上兩種都可選,這里選擇使用窗體;

** 分析效果:**

<img width="320" height="500" src="http://upload-images.jianshu.io/upload_images/1599843-22783f34fe74287a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"/>

1、分為三部分、固定圓C0、拖拽圓C1、中間粘性連接部分
2、拖拽 :在一定范圍內,C1 距離越遠、C0半徑變小,中間區域變長變細(物理老師說過,物體在變長的時候會變細,沒有一個物體能在變長的同時變粗。哈哈);
3、拖拽:移動半徑超過閾值后 固定圓與連接部分消失;
4、松手:拖拽半徑從未超過閾值,會出現一個回彈效果;
5、松手:拖拽過程中拖拽半徑有超過閾值,最終在閾值范圍內松手,位置還原、不會出現任何動畫效果。
6、松手:在閾值范圍外松手,會出現一個爆炸效果;

實現技術

自定義View,使用貝塞爾曲線繪制中間粘性區域;
事件處理;
屬性動畫,做回彈效果;
幀動畫,做爆炸效果;

** 繪制 **
以上 技術已經確定好了;
接下來就是數學了。
畫出幾何圖(切點 ABCD,控制點Z,固定圓半徑 rc0,角度 a,b);


1.png

現在已知變量 固定圓 r0,拖拽點 r1的坐標,能得到 控制點(中點)Z 的坐標; 自然能得到 cos(a),sin(a)的值;

dx = r1.x - r0.x;
dy = r1 - r0.y;
length = (float) Math.sqrt(Math.pow(dx, 2.0D) + Math.pow((double) dy, 2.0D));
cos(a) = dx / mDraglength;
sin(a) = dy / mDraglength;

計算 點A 的坐標

A.x = r0.x+rc0*cos(b)= r0.x+rc0*cos(a+(π*3/2))= r0.x+rc0*sina;
A.y= r0.y+rc0*sin(b)= r0.y+rc0*sin(a+(π*3/2))= r0.y+rc0*cos(a);

B的與A對稱, 能相對應的算出B點坐標;
AB與CD 平行,CD兩點的坐標那真是呼之欲出;

那么這個繪制就沒有問題了,至于貝塞爾曲線等 繪制類基礎代碼啥的,請自行百度。

實現基本繪制代碼

** 懸浮 **

WindowManager   windowManager = getWindowManager();  //得到對象
// 添加到當前的窗口上  
windowManager.addView(img, params);  
windowManager.removeView(img);  

** 優化、封裝 **

『發現變化并且封裝變化』

減少繪制;
減少計算;
多使用系統 Math 的計算,因為底層調用NDK;
計算抽離;
封裝調用類 ;

最終代碼:[ StickyDot ] (https://github.com/LidongWen/StickyDot


希望我的文章不會誤導在觀看的你,如果有異議的地方歡迎討論和指正。
如果能給觀看的你帶來收獲,那就是最好不過了。

人生得意須盡歡, 桃花塢里桃花庵
點個關注唄,對,不信你點試試?
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容