Android利用控制點的拖拽畫一個粽子
前言
上一篇我們通過Listener
獲取觸控點的位置作為貝塞爾曲線的控制點,實現(xiàn)曲線的交互式繪制。不過,上一篇有個缺陷,控制點繪制完成后只能撤銷,沒法修改,如果要調(diào)整繪制的圖形的話會非常麻煩,這一篇我們來實現(xiàn)控制點的拖拽式移動,動態(tài)調(diào)整位置來調(diào)整繪制的圖形。
實現(xiàn)邏輯
上一篇的主要代碼我們不做更改,主要是需要實現(xiàn)控制點的拖拽式移動,移動過程中動態(tài)繪制新的曲線。不過由于繪制過程中不能同時移動點,因此需要有個完成繪制的控制,完成繪制后才支持拖拽控制點。拖拽控制點實現(xiàn)這里有兩個主要邏輯:
- 控制點的命中判斷:即拖拽開始時判斷哪個控制點被命中,需要移動。
- 監(jiān)聽觸控位置的移動過程:移動過程中動態(tài)繪制新的圖形,以便直接看到對應(yīng)的效果。
控制點的命中判斷在完成繪制后,首先需要監(jiān)聽觸控按下事件,看看觸控點是否覆蓋了某個控制點的觸控響應(yīng)范圍,同時對于距離較近的點,可能會同時命中多個點的觸控響應(yīng)范圍,這個時候需要取距離最近的那個點。對于觸控范圍,我們定義為每個觸控點的周邊10個像素點。命中觸控點的實現(xiàn)代碼如下:
int checkPointToMove(Offset pressedPoint) { // 控制點非空才查找 if (points.isNotEmpty) { var pointsToCheck = <Offset>[]; final maxDistance = 10.0; // 查找觸控響應(yīng)范圍內(nèi)的控制點 for (Offset p in points) { if ((p.dx - pressedPoint.dx).abs() < maxDistance && (p.dy - pressedPoint.dy).abs() < maxDistance) { pointsToCheck.add(p); } } // 未找到 if (pointsToCheck.length == 0) { return -1; } else if (pointsToCheck.length == 1) { // 只有一個點,直接返回 return points.indexOf(pointsToCheck[0]); } else { // 有多個點命中,找到距離最近的點返回 Offset point = pointsToCheck[0]; var distance = distanceBetween(pointsToCheck[0], pressedPoint); for (int i = 1; i < pointsToCheck.length; i++) { var newDistance = distanceBetween(pointsToCheck[i], pressedPoint); if (newDistance < distance) { point = pointsToCheck[i]; distance = newDistance; } } return points.indexOf(point); } } return -1; }
移動過程的處理就比較簡單了,我們已經(jīng)找到了命中的控制點,那就在觸控位置移動監(jiān)聽響應(yīng)方法onPointerMove
中更新控制點位置,并重新繪制即可,代碼如下,其中indexOfPointToMove
是一個狀態(tài)變量,即找到的控制點下標(biāo):
onPointerMove: ((event) { if (indexOfPointToMove != -1) { points[indexOfPointToMove] = event.localPosition; setState(() {}); } }),
應(yīng)用
邏輯完成了,我們就來做一個繪制應(yīng)用吧??紤]端午節(jié)快到了,我們嘗試來繪制一個粽子的線條畫看看。下面是調(diào)整前后的對比效果以及調(diào)整過程的動圖,可以看到,調(diào)整后的還是更像粽子一些。
總結(jié)
本篇介紹了如何通過拖拽調(diào)整貝塞爾曲線繪制的控制點來調(diào)整圖形的繪制,實際上很多繪圖都可能用到拖拽式的控制點位的調(diào)整,比如電子圍欄的設(shè)置。實際上主要的代碼是判斷觸控位置命中了具體哪個控制點。本篇代碼已經(jīng)上傳至:繪圖相關(guān)代碼。
以上就是Android利用控制點的拖拽畫一個粽子的詳細(xì)內(nèi)容,更多關(guān)于Android粽子的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Genymotion模擬器常見問題整理與相應(yīng)解決方法
為什么說是常見問題整合呢,因為小編我就是Genymotion模板器最悲劇的使用者,該見過的問題,我基本都見過了,在此總結(jié)出這血的教訓(xùn),望大家不要重蹈覆轍2018-03-03Android中SharedPreferences簡單使用實例
這篇文章主要介紹了Android中SharedPreferences簡單使用案例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-10-10Android開發(fā)中使用外部應(yīng)用獲取SD卡狀態(tài)的方法
這篇文章主要介紹了Android開發(fā)中使用外部應(yīng)用獲取SD卡狀態(tài)的方法,簡單分析了Android監(jiān)聽SD卡狀態(tài)的方法,并結(jié)合實例形式分析了Android外部應(yīng)用獲取SD卡狀態(tài)的相關(guān)操作技巧,需要的朋友可以參考下2017-11-11Android中findViewById獲取控件返回為空問題怎么解決
這篇文章主要介紹了Android中findViewById獲取控件返回為空問題怎么解決的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-06-06Android端權(quán)限隱私的合規(guī)化處理實戰(zhàn)記錄
大家應(yīng)該都發(fā)現(xiàn)了,現(xiàn)在很多應(yīng)用市場都要求應(yīng)用上架需要用戶協(xié)議,這篇文章主要給大家介紹了關(guān)于Android端權(quán)限隱私合規(guī)化處理的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-08-08