Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android利用貝塞爾曲線實現ScrollView滑動到頂部後陰影反饋效果

Android利用貝塞爾曲線實現ScrollView滑動到頂部後陰影反饋效果

編輯:關於Android編程

當ScrollView滑動到頂部後,根據手指在屏幕上繼續下拉出現的陰影效果的簡單實現方式,僅供學習參考,在實際項目中引用還需慎重!!!

技術點:

1、利用Path中的moveTo() 、quadTo()方法實現的二階貝塞爾曲線生成陰影

moveTo()方法就不做過多的介紹了,可以簡單的理解為一個起始點。而quadTo()方法是android為開發者提供的一個生成二階貝塞爾曲線方法,一段曲線用二階足以!當然,還有三階貝塞爾曲線生成方法:cubicTo(),然而android也只為我們提供到三階,因為更高階的貝塞爾曲線可以通過結合二階和一階來實現,其實貝塞爾曲線的核心就在於那個控制點,比如二階曲線的控制點數量為1,三階曲線的控制點數量為2... n階曲線的控制點數量為n-1,以此類推。cubicTo()方法需要四個參數,這四個參數是干什麼用的,或者說是怎麼去傳呢?前兩個就是我們所說的核心:控制點坐標x,y,而後兩個參數也是需要一個坐標,就是與moveTo()方法之對應的終點坐標,就好比moveTo()方法和lineTo方法成對使用是一個道理,要畫一條直線肯定至少需要兩個點:moveTo()是起點lineTo()是終點,而畫一個二階貝塞爾曲線也要依賴兩個點moveTo()是起點,quadTo()的後兩個參數為終點。好了,曲線出來了,那麼怎麼讓曲線以上的部分變成陰影呢?實現也簡單,設置好畫筆就可以了,利用Paint的setStyle()方法傳遞Paint.Style.FILL參數即可,最後傳入帶有透明度的顏色即可,效果如下圖

 

\

 

2、如何根據手勢滑動來控制這段曲線?

這個問題也是實現此效果的核心,當然也是很簡單的,簡單的說下思路。首先我們要重寫已經玩爛的onTouchEvent()方法,在 ACTION_DOWN中記錄下手指按下的Y坐標,在ACTION_MOVE中算出實時的距離:就是當前手指的位置 - 初始按下的位置 ,就像這樣

 

\

 

然後我們將上面介紹過的貝塞爾曲線畫法封裝一下就像這樣:

 

\

 

因為需求確定,起始點就定在了屏幕的左上角,終點就定在屏幕的右上角,只需傳入控制點即可但是我們如果無限的向屏幕下方滑動那麼貝塞爾曲線的弧度也就越大,是不是感覺弧度太大也不是很美觀,所以就要對他進行約束。這個約束條件就是當我們滑動Y的距離超過屏幕的1/10時就讓這個距離固定在屏幕高度的1/10,如果小於1/10那麼就根據我們手指移動的距離來與用戶交互。

最後我們在onDraw()方法中調用它就行了,需要強調的是最後一定要調用canvas中的drawPath()方法,這個Path參數就是我們生成的貝塞爾曲線。

3、當手松開時,這段曲線如何平滑過渡到初始位置?

此處的實現方式應該有很多種,這裡我使用的是子線程進行多次計算然後通知主線程刷新UI的方式實現的。當我們在onTouchEvent方法中監聽到ACTION_UP時我們就要讓這段曲線復原,並且是平滑過渡回初始的位置,先上代碼為敬:

 

\

 

這段是執行在子線程中的,可能你發現使用了synchronized關鍵字,為什麼要用它?不用不行嗎? 當然,不用也可以,效果沒有沒麼好而已。當我們遇到手指多次去滑動屏幕時我們的onTouchEvent方法就會不斷的響應我們,當我們劃一次就會開一條子線程去執行release()方法,那麼假設我現在劃過第一次後線程還沒執行完畢,我又劃了第二次此時就會有兩條線程在運行,而我們的陰影還沒有復位又開始了下一次的計算並且更新UI那不亂套才怪呢,用戶體驗就很差。所以我們要對線程加個鎖,當我這條線程沒計算完畢時新的線程就休想執行,使用synchronized簡單的實現了我們這個復雜的業務需求;剩下的就很簡單了就是如何平滑的滾回去?當松開手時計算好的距離又一次派上用場了,因為這段曲線就是從這裡平滑的滾回原位,從這個距離開始遞減一直到0為止。

最後附上項目地址:https://github.com/415192022/PathDemo

希望能給些star給我一些支持,謝謝大家!

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved