旧版的问题
-
共享时间
-
点击完 View A后,在限定时间无法点击View B
最新版的使用方式
针对Kotlin和新代码
addTestItem("验证DebounceClick", {}).setDebouncedOnClickListener {
smartLog {
"验证DebounceClick v=$it"
}
}
addTestItem("验证DebounceClick 2秒延迟", {}).setDebouncedOnClickListener(2000L) {
smartLog {
"验证DebounceClick 2秒延迟 v=$it"
}
}
针对旧代码或者Java代码
@Override
public void onItemClickListener(View v, Object data, int position) {
if (data == null) {
return;
}
if (ViewClickDebouncer.INSTANCE.isFastClick(v)) {
LogUtils.debugInfo("onItemClickListener isFastClick");
return;
}
//实际的处理逻辑
}
API 源码
fun View?.setDebouncedOnClickListener(debounceTimeOutInMills: Long? = null, onClickListener: ((View?) -> Unit)?) {
this ?: return
onClickListener ?: return
ViewClickDebouncer.setupViewDebounceTimeout(this, debounceTimeOutInMills)
this.doOnClick {
if (!ViewClickDebouncer.isFastClick(it)) {
onClickListener.invoke(it)
}
}
}
fun View?.setDebouncedOnClickListener(onClickListener: ((View?) -> Unit)?) {
this.setDebouncedOnClickListener(null, onClickListener)
}
package com.secoo.commonsdk.utils
import android.view.View
import com.secoo.commonsdk.ktx.alsoWithLog
import com.secoo.commonsdk.ktx.smartLog
import java.util.*
/**
* View防快速点击处理
*/
object ViewClickDebouncer: View.OnAttachStateChangeListener {
private const val THRESHOLD_DEBOUNCE_IN_MILLS = 500L
private val viewClickDebounceMap: WeakHashMap<View, Debounce<View>> = WeakHashMap()
/**
* 获取View快速点击控制
*/
private fun getViewDebounce(view: View?, thresholdInMills: Long? = THRESHOLD_DEBOUNCE_IN_MILLS): Debounce<View>? {
view ?: return null
return viewClickDebounceMap[view] ?: onCreateViewDebounce(view, thresholdInMills).also {
viewClickDebounceMap[view] = it
}
}
fun setupViewDebounceTimeout(view: View?, debounceTimeOutInMills: Long?) {
view ?: return
viewClickDebounceMap.remove(view)
getViewDebounce(view, debounceTimeOutInMills)
}
private fun onCreateViewDebounce(view: View, thresholdInMills: Long?): Debounce<View> {
view.addOnAttachStateChangeListener(this)
val finalThreshold = thresholdInMills ?: THRESHOLD_DEBOUNCE_IN_MILLS
return Debounce<View>(finalThreshold).alsoWithLog(this) {
"createViewDebounce view=$view; finalThreshold=$finalThreshold"
}
}
/**
* 是否是快速点击
*/
fun isFastClick(view: View?): Boolean {
view ?: return false.alsoWithLog(this) {
"isTooFast view is null;return false"
}
val debounce = getViewDebounce(view)
debounce ?: return false.alsoWithLog(this) {
"isTooFast debounce is null;return false"
}
return debounce.updateValue(view).not().alsoWithLog(this) {
"isTooFast return $it;view=$view"
}
}
override fun onViewDetachedFromWindow(view: View?) {
smartLog {
"onViewDetachedFromWindow view=$view"
}
view ?: return
view.removeOnAttachStateChangeListener(this)
viewClickDebounceMap.remove(view)
}
override fun onViewAttachedToWindow(view: View?) {
smartLog {
"onViewAttachedToWindow view=$view"
}
}
}