錄音需求中,往往有兩種常規操作。 長按基本實現流程: 監聽觸摸事件,按下時錄製,抬起時停止。 點擊基本流程: 點擊開始錄製,在次點擊停止錄製 但是凡事有絕對,如果需要同時支持長按錄製抬起結束跟點擊錄製在次點擊結束呢?面對如此無理的需求,從技術層面上怎麼如絲滑般去相容呢。 需要兩者相容,只能從觸摸事件 ...
錄音需求中,往往有兩種常規操作。
長按基本實現流程:
監聽觸摸事件,按下時錄製,抬起時停止。
點擊基本流程:
點擊開始錄製,在次點擊停止錄製
但是凡事有絕對,如果需要同時支持長按錄製抬起結束跟點擊錄製在次點擊結束呢?面對如此無理的需求,從技術層面上怎麼如絲滑般去相容呢。
需要兩者相容,只能從觸摸事件入手了,這裡的重點其實就在於怎麼在觸摸事件中去區分點擊事件跟觸摸事件。
功能可能並不難,但是沒有一個好的思路,就會導致代碼邏輯混亂,不好維護,並且代碼過多,不夠簡潔。
先看效果圖,前面是點擊事件,後面是觸摸長按。
首先把開始錄製跟結束方法寫好,在觸摸事件里,按下時錄製,抬起時結束,等於是長按錄製的邏輯
在此基礎上想要相容點擊邏輯,其實只要一個限制就行,那就是點擊的時間。
正常情況下我點擊後依次經歷了按下跟抬起兩個事件(觸摸不做處理),那我加個點擊時間,如果間隔小於800毫秒,就不做處理。
這時候我點擊只會觸發一次按下事件,等我下次點擊時,已經超過了800毫秒,並且可以防止快速點擊,一舉兩得(快速點擊錄製時長過短,需要限制,禁止無意義操作)。
在回到觸摸邏輯,我點擊錄製,不鬆手,超過800毫秒,此時我在抬起,直接觸發抬起事件,邏輯如絲滑般柔順。
ivRecord.setOnTouchListener { _, event -> if (abs(System.currentTimeMillis() - downTimeInMillis) >= 800L) { when (event.action) { MotionEvent.ACTION_DOWN -> { start() } MotionEvent.ACTION_CANCEL, MotionEvent.ACTION_UP -> { stop() } } } true }
一行 if 判斷,完美相容兩種錄製模式,簡單明瞭。