Android MIUI 即刻APP 返回手勢及動畫 探索

swipe_left.jpeg

swipe_right.jpeg

18 年底做 Readhub APP 時就加入了這個返回動畫效果。一直到現在,才有時間來簡單總結和封裝一下。

swipeback.gif

不知道這個返回手勢動畫到底是 MIUI 還是「即刻」APP 首創,因為我那會兒還沒用上 MIUI 全面屏。不過 MIUI 全面屏那個返回手勢相對簡單,固定位置。從這個效果上看,我覺得是 MIUI 先有這個效果,然后 「即刻」APP 優化豐富了一下。當然,可能還有另外一種情況,這是早就有的效果圖,只是在目前,我已知有使用的就上面兩個場景。

總結起來很簡單,就是一個「貝塞爾曲線」的繪制,再外加一個箭頭繪制。箭頭什么的的繪制在之前的倉庫中已經練習過很多。這次著重說說這個特殊圖形需要怎么繪制。

對于貝塞爾曲線繪制,之前玩過兩階、三階的。第一次看到這個效果,覺得貝塞爾曲能實現,但是這是幾階的,高階的怎么玩,那就是從頭開始。

在經過一番把玩探索后,最終確定這就是五階的貝塞爾曲線, Android 似乎默認沒有高階對應的 api 。

貝塞爾曲線.png

那這怎么辦呢?曲線就是函數嘛,肯定有公式,網上就搜到公式寫法。

private fun calculateY(i: Int, j: Int, t: Float): Float {
    return if (i == 1) {
        (1 - t) * controlPoints[j].y + t * controlPoints[j + 1].y
    } else (1 - t) * calculateY(i - 1, j, t) + t * calculateY(i - 1, j + 1, t)
}

controlPoints 對應的就是那個五個控制點的集合。

addControlPoint(0, 0f, yResult - maxPeakValue * 1.5f)
addControlPoint(1, 0f, yResult - maxPeakValue * 1.5f * GOLDEN_RATIO)
addControlPoint(2, min, yResult)
addControlPoint(3, 0f, yResult + maxPeakValue * 1.5f * GOLDEN_RATIO)
addControlPoint(4, 0f, yResult + maxPeakValue * 1.5f)

接著就是控制是否攔截事件,我現在是做成 Helper 這種工具類型,和對應的 ViewGroup 是解耦的,其實就是 ViewDragHelper 的一個簡單實現。

對了,最后考慮下來,實現了左右兩邊的滑動效果。至于上下,我覺得這種場景不大,就懶得去做了。

具體代碼細節就不貼了,源碼也沒多少,這里講遇到的一些細節問題或者寫出來的 bug

返回退出應用后,后臺程序預覽中存在返回手勢效果

這里其實就是一個先后問題,一開始是同步執行 invalidate()onBackReleased() 。后來使用 Runnable + postDalay() 來延遲 onBackReleased() 執行。

貝塞爾曲線貼近屏幕的地方總有一個像素的白線

這里后面排查出來是我添加控制點,for 循環時角標是[0,length-1],最后一個沒有添加計算到,所以計算出來的控制點就少了一個。最終效果就是繪制出來的圖形 x 軸沒有完全對稱。偏差就在 1px 左右。
最后的效果就是總感覺下方有一跟白線。

for 循環處理好之后,發現右邊繪制出來還是會有這個情況,具體原因不清楚,因為單看數據層面,它肯定是貼邊的。最后很討巧,使用到 translate()Canvas 平移一個像素規避掉,這簡直是程序員的小巧思,哈哈 ??。

控制點數量及緩存

因為是用公式算的控制點,所以每一次繪制,其實簡單理解就是講一個一個點連接成一條曲線的。那么問題就是,點多,曲線當然最逼真,但是單位時間處理的數據量就上去了。
點少,可能你看到就是折線圖了。
最后均衡在 50 個控制點,點與點之間的比例就是 2% 。在繪制等方法中肯定不能頻繁創建對象,所以這 50 個點需要復用。

倉庫地址

lovejjfg/SwipeBack 現已同步 jcenter 。 詳情請移步 README.md

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 案主相關信息:30,未婚,女;作畫順序:樹、太陽、房子、人(畫人的時候想了很久,最后發現手不知道要怎么畫) 需求是...
    bobo_ccd9閱讀 276評論 0 0
  • 好久不上了,冒個泡。
    杺栯欞樨閱讀 412評論 2 10
  • 又是一年秋風吹, 不讓百花昏昏欲睡。 遠遠的,我聞到丹桂的香味。 真是,遠遠的。 花壇旁,寫生的同學, 手拿著鉛筆...
    phantomses閱讀 479評論 0 1
  • 在最美好的年級里好好打理自己的外貌以及肉體,不要胡吃海塞!! 掌握好學習方法以及最終目的,然后好好的專注在那個領域...
    麋鹿Mona閱讀 157評論 0 0