import android.content.Context
import android.os.SystemClock
import android.util.AttributeSet
import android.view.MotionEvent
import android.widget.Button
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flow
import kotlin.math.max
class RollBackButton @JvmOverloads constructor(
? ? context: Context,
? ? attrs: AttributeSet? = null,
? ? defStyleAttr: Int = 0
) : Button(context, attrs, defStyleAttr) {
? ? // 配置參數(shù)
? ? var longPressDuration = 500L // 默認(rèn)500毫秒
? ? var repeatInterval = 150L // 默認(rèn)150毫秒
? ? // 事件回調(diào)接口
? ? interface OnRollBackButtonListener {
? ? ? ? fun onLongPress()
? ? ? ? fun onShortPress()
? ? ? ? fun onRelease()
? ? }
? ? private var listener: OnRollBackButtonListener? = null
? ? private var job: Job? = null
? ? private val eventFlow = MutableSharedFlow<Event>()
? ? // 設(shè)置事件監(jiān)聽器
? ? fun setOnRollBackButtonListener(listener: OnRollBackButtonListener) {
? ? ? ? this.listener = listener
? ? ? ? // 啟動協(xié)程來收集事件
? ? ? ? CoroutineScope(Dispatchers.Main).launch {
? ? ? ? ? ? eventFlow.collect { event ->
? ? ? ? ? ? ? ? when (event) {
? ? ? ? ? ? ? ? ? ? is Event.LongPress -> listener?.onLongPress()
? ? ? ? ? ? ? ? ? ? is Event.ShortPress -> listener?.onShortPress()
? ? ? ? ? ? ? ? ? ? is Event.Release -> listener?.onRelease()
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? private sealed class Event {
? ? ? ? object LongPress : Event()
? ? ? ? object ShortPress : Event()
? ? ? ? object Release : Event()
? ? }
? ? override fun onTouchEvent(event: MotionEvent): Boolean {
? ? ? ? when (event.action) {
? ? ? ? ? ? MotionEvent.ACTION_DOWN -> {
? ? ? ? ? ? ? ? job?.cancel() // 取消之前的長按任務(wù)
? ? ? ? ? ? ? ? job = CoroutineScope(Dispatchers.Main).launch {
? ? ? ? ? ? ? ? ? ? val startTime = SystemClock.elapsedRealtime()
? ? ? ? ? ? ? ? ? ? delay(longPressDuration)
? ? ? ? ? ? ? ? ? ? if (SystemClock.elapsedRealtime() - startTime >= longPressDuration) {
? ? ? ? ? ? ? ? ? ? ? ? // 長按事件
? ? ? ? ? ? ? ? ? ? ? ? eventFlow.emit(Event.LongPress)
? ? ? ? ? ? ? ? ? ? ? ? // 重復(fù)觸發(fā)長按事件
? ? ? ? ? ? ? ? ? ? ? ? while (SystemClock.elapsedRealtime() - startTime >= longPressDuration) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? delay(repeatInterval)
? ? ? ? ? ? ? ? ? ? ? ? ? ? eventFlow.emit(Event.LongPress)
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? return true
? ? ? ? ? ? }
? ? ? ? ? ? MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
? ? ? ? ? ? ? ? job?.cancel()
? ? ? ? ? ? ? ? val elapsedTime = SystemClock.elapsedRealtime() - event.downTime
? ? ? ? ? ? ? ? if (elapsedTime < longPressDuration) {
? ? ? ? ? ? ? ? ? ? eventFlow.emit(Event.ShortPress)
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? eventFlow.emit(Event.Release)
? ? ? ? ? ? ? ? return true
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? return super.onTouchEvent(event)
? ? }
}
class MainActivity : AppCompatActivity() {
? ? override fun onCreate(savedInstanceState: Bundle?) {
? ? ? ? super.onCreate(savedInstanceState)
? ? ? ? setContentView(R.layout.activity_main)
? ? ? ? val rollBackButton: RollBackButton = findViewById(R.id.roll_back_button)
? ? ? ? rollBackButton.setOnRollBackButtonListener(object : RollBackButton.OnRollBackButtonListener {
? ? ? ? ? ? override fun onLongPress() {
? ? ? ? ? ? ? ? // 處理長按事件
? ? ? ? ? ? ? ? Toast.makeText(this@MainActivity, "Long press detected", Toast.LENGTH_SHORT).show()
? ? ? ? ? ? }
? ? ? ? ? ? override fun onShortPress() {
? ? ? ? ? ? ? ? // 處理按下時(shí)間過短事件
? ? ? ? ? ? ? ? Toast.makeText(this@MainActivity, "Short press detected", Toast.LENGTH_SHORT).show()
? ? ? ? ? ? }
? ? ? ? ? ? override fun onRelease() {
? ? ? ? ? ? ? ? // 處理松手事件
? ? ? ? ? ? ? ? Toast.makeText(this@MainActivity, "Release detected", Toast.LENGTH_SHORT).show()
? ? ? ? ? ? }
? ? ? ? })
? ? }
}