18 年底做 Readhub APP 時就加入了這個返回動畫效果坯汤。一直到現(xiàn)在福压,才有時間來簡單總結(jié)和封裝一下。
不知道這個返回手勢動畫到底是 MIUI 還是「即刻」APP 首創(chuàng),因為我那會兒還沒用上 MIUI 全面屏堵第。不過 MIUI 全面屏那個返回手勢相對簡單兆旬,固定位置假抄。從這個效果上看,我覺得是 MIUI 先有這個效果丽猬,然后 「即刻」APP 優(yōu)化豐富了一下宿饱。當(dāng)然,可能還有另外一種情況脚祟,這是早就有的效果圖谬以,只是在目前,我已知有使用的就上面兩個場景由桌。
總結(jié)起來很簡單为黎,就是一個「貝塞爾曲線」的繪制,再外加一個箭頭繪制行您。箭頭什么的的繪制在之前的倉庫中已經(jīng)練習(xí)過很多铭乾。這次著重說說這個特殊圖形需要怎么繪制。
對于貝塞爾曲線繪制娃循,之前玩過兩階炕檩、三階的。第一次看到這個效果捌斧,覺得貝塞爾曲能實現(xiàn)笛质,但是這是幾階的,高階的怎么玩捞蚂,那就是從頭開始妇押。
在經(jīng)過一番把玩探索后,最終確定這就是五階的貝塞爾曲線姓迅, Android
似乎默認(rèn)沒有高階對應(yīng)的 api 敲霍。
那這怎么辦呢?曲線就是函數(shù)嘛队贱,肯定有公式色冀,網(wǎng)上就搜到公式寫法。
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 對應(yīng)的就是那個五個控制點的集合柱嫌。
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)
接著就是控制是否攔截事件锋恬,我現(xiàn)在是做成 Helper 這種工具類型,和對應(yīng)的 ViewGroup
是解耦的编丘,其實就是 ViewDragHelper
的一個簡單實現(xiàn)与学。
對了彤悔,最后考慮下來,實現(xiàn)了左右兩邊的滑動效果索守。至于上下晕窑,我覺得這種場景不大,就懶得去做了卵佛。
具體代碼細節(jié)就不貼了杨赤,源碼也沒多少,這里講遇到的一些細節(jié)問題或者寫出來的 bug
返回退出應(yīng)用后截汪,后臺程序預(yù)覽中存在返回手勢效果
這里其實就是一個先后問題疾牲,一開始是同步執(zhí)行 invalidate()
和 onBackReleased()
。后來使用 Runnable
+ postDalay()
來延遲 onBackReleased()
執(zhí)行衙解。
貝塞爾曲線貼近屏幕的地方總有一個像素的白線
這里后面排查出來是我添加控制點阳柔,for 循環(huán)時角標(biāo)是[0,length-1],最后一個沒有添加計算到,所以計算出來的控制點就少了一個蚓峦。最終效果就是繪制出來的圖形 x 軸沒有完全對稱舌剂。偏差就在 1px 左右。
最后的效果就是總感覺下方有一跟白線暑椰。
for 循環(huán)處理好之后霍转,發(fā)現(xiàn)右邊繪制出來還是會有這個情況,具體原因不清楚一汽,因為單看數(shù)據(jù)層面谴忧,它肯定是貼邊的。最后很討巧角虫,使用到 translate()
將 Canvas
平移一個像素規(guī)避掉,這簡直是程序員的小巧思委造,哈哈 ??戳鹅。
控制點數(shù)量及緩存
因為是用公式算的控制點,所以每一次繪制昏兆,其實簡單理解就是講一個一個點連接成一條曲線的枫虏。那么問題就是,點多爬虱,曲線當(dāng)然最逼真隶债,但是單位時間處理的數(shù)據(jù)量就上去了。
點少跑筝,可能你看到就是折線圖了死讹。
最后均衡在 50 個控制點,點與點之間的比例就是 2% 曲梗。在繪制等方法中肯定不能頻繁創(chuàng)建對象赞警,所以這 50 個點需要復(fù)用妓忍。
倉庫地址
lovejjfg/SwipeBack 現(xiàn)已同步 jcenter 太闺。 詳情請移步 README.md