104 lines
3.0 KiB
Kotlin
104 lines
3.0 KiB
Kotlin
package com.sw.platecabinet.ext
|
||
|
||
import android.os.Handler
|
||
import android.os.Looper
|
||
import android.view.View
|
||
import android.widget.TextView
|
||
import kotlinx.coroutines.CoroutineScope
|
||
import kotlinx.coroutines.Dispatchers
|
||
import kotlinx.coroutines.Job
|
||
import kotlinx.coroutines.delay
|
||
import kotlinx.coroutines.launch
|
||
|
||
/**
|
||
* 设置 TextView 的双击和单击事件监听器
|
||
* @param doubleClickInterval 双击间隔时间(毫秒),默认 300ms
|
||
* @param onDoubleClick 双击回调
|
||
* @param onSingleClick 单击回调
|
||
*/
|
||
fun TextView.setClickListeners(
|
||
doubleClickInterval: Long = 300,
|
||
onDoubleClick: (View) -> Unit = {},
|
||
onSingleClick: (View) -> Unit = {}
|
||
) {
|
||
var clickCount = 0
|
||
val handler = Handler(Looper.getMainLooper())
|
||
|
||
setOnClickListener { view ->
|
||
clickCount++
|
||
handler.postDelayed({
|
||
if (clickCount == 1) {
|
||
onSingleClick(view)
|
||
} else if (clickCount == 2) {
|
||
onDoubleClick(view)
|
||
}
|
||
clickCount = 0 // 重置计数
|
||
}, doubleClickInterval)
|
||
}
|
||
}
|
||
|
||
fun View.clickWithCoroutines(
|
||
doubleClickInterval: Long = 300,
|
||
onDoubleClick: (View) -> Unit = {},
|
||
onSingleClick: (View) -> Unit = {}
|
||
) {
|
||
var pendingItem: View? = null
|
||
var lastClickTime: Long = 0
|
||
var clickJob: Job? = null
|
||
|
||
setOnClickListener { view ->
|
||
val currentTime = System.currentTimeMillis()
|
||
|
||
// 如果是同一控件且在双击间隔内,则判定为双击
|
||
if (pendingItem === view && currentTime - lastClickTime < doubleClickInterval) {
|
||
// 取消之前的单击任务
|
||
clickJob?.cancel()
|
||
onDoubleClick(view)
|
||
pendingItem = null
|
||
} else {
|
||
// 取消之前的单击任务
|
||
clickJob?.cancel()
|
||
|
||
// 启动新的单击任务
|
||
clickJob = CoroutineScope(Dispatchers.Main).launch {
|
||
delay(doubleClickInterval)
|
||
onSingleClick(view)
|
||
}
|
||
|
||
pendingItem = view
|
||
lastClickTime = currentTime
|
||
}
|
||
}
|
||
}
|
||
|
||
//fun View.clickWithDebounce(delay: Long = 500, action: () -> Unit) {
|
||
// var job: Job? = null
|
||
// setOnClickListener {
|
||
// job?.cancel()
|
||
// job = CoroutineScope(Dispatchers.Main).launch {
|
||
// delay(delay)
|
||
// action()
|
||
// }
|
||
// }
|
||
//}
|
||
|
||
/**
|
||
* 极简版防重复点击扩展函数
|
||
* @param delay 防抖时间(默认300ms)
|
||
* @param action 点击执行逻辑
|
||
*/
|
||
fun View.clickWithDebounce(delay: Long = 500, action: () -> Unit) {
|
||
setOnClickListener {
|
||
// 用View的tag存储是否可点击的状态(默认可点击)
|
||
if (tag as? Boolean ?: true) {
|
||
tag = false // 标记为不可点击
|
||
action() // 立即执行点击逻辑
|
||
|
||
// 启动协程,延迟后恢复可点击状态
|
||
CoroutineScope(Dispatchers.Main).launch {
|
||
delay(delay)
|
||
tag = true // 恢复可点击
|
||
}
|
||
}
|
||
}
|
||
} |