[更新]:
1.新增OnLazyClickListener
[2019.6.30]
2.triggerLastTime = currentClickTime
挪到if判斷內(nèi),解決多次快速點擊失效bug [2020.10.28]
在Android的代碼實現(xiàn)中羽圃,我們不可避免的會經(jīng)常跟點擊事件setOnClickListener打交道持舆。
而重復(fù)點擊又是我們不得不面對的問題甸怕。
Java實現(xiàn)
如果用java,我們可以寫一個工具類處理,比如:
public class Utils {
private static final int MIN_DELAY_TIME = 1000; // 兩次點擊間隔不能少于1000ms
private static long lastClickTime;
public static boolean clickEnable() {
boolean flag = false;
long currentClickTime = System.currentTimeMillis();
if ((currentClickTime - lastClickTime) >= MIN_DELAY_TIME) {
flag = true;
}
lastClickTime = currentClickTime;
return flag;
}
}
Rxjava實現(xiàn)
如果Rxjava宪塔,我們可以很方便的利用第三方庫Rxbinding的Rxview.clicks處理
RxView.clicks(view)
.throttleFirst(1, TimeUnit.SECONDS)
.subscribe {
...
}
Kotlin擴展實現(xiàn)
當(dāng)我們切換到kotlin,便可以利用它的擴展函數(shù)和擴展屬性來打造我們的點擊事件囊拜。
具體代碼如下:
/***
* 設(shè)置延遲時間的View擴展
* @param delay Long 延遲時間某筐,默認(rèn)600毫秒
* @return T
*/
fun <T : View> T.withTrigger(delay: Long = 600): T {
triggerDelay = delay
return this
}
/***
* 點擊事件的View擴展
* @param block: (T) -> Unit 函數(shù)
* @return Unit
*/
fun <T : View> T.click(block: (T) -> Unit) = setOnClickListener {
block(it as T)
}
/***
* 帶延遲過濾的點擊事件View擴展
* @param delay Long 延遲時間,默認(rèn)600毫秒
* @param block: (T) -> Unit 函數(shù)
* @return Unit
*/
fun <T : View> T.clickWithTrigger(time: Long = 600, block: (T) -> Unit){
triggerDelay = time
setOnClickListener {
if (clickEnable()) {
block(it as T)
}
}
}
private var <T : View> T.triggerLastTime: Long
get() = if (getTag(1123460103) != null) getTag(1123460103) as Long else -601
set(value) {
setTag(1123460103, value)
}
private var <T : View> T.triggerDelay: Long
get() = if (getTag(1123461123) != null) getTag(1123461123) as Long else 600
set(value) {
setTag(1123461123, value)
}
private fun <T : View> T.clickEnable(): Boolean {
var flag = false
val currentClickTime = System.currentTimeMillis()
if (currentClickTime - triggerLastTime >= triggerDelay) {
flag = true
triggerLastTime = currentClickTime
}
return flag
}
/***
* 帶延遲過濾的點擊事件監(jiān)聽冠跷,見[View.OnClickListener]
* 延遲時間根據(jù)triggerDelay獲饶咸堋:600毫秒,不能動態(tài)設(shè)置
*/
interface OnLazyClickListener : View.OnClickListener {
override fun onClick(v: View?) {
if (v?.clickEnable() == true) {
onLazyClick(v)
}
}
fun onLazyClick(v: View)
}
用法:
直接新建一個kt文件蜜托,將上述代碼直接復(fù)制進(jìn)去抄囚,便可如下使用:
//不帶過濾的普通點擊
view.click {
L.e("aaron click test")
}
//帶默認(rèn)600毫秒過濾的點擊事件(方法1)
view.clickWithTrigger {
L.e("aaron clickWithTrigger test")
}
//帶默認(rèn)600毫秒過濾的點擊事件(方法2)
view.withTrigger().click {
L.e("aaron click test")
}
//帶700毫秒過濾的點擊事件(方法1)
bind.clickWithTrigger(700) {
L.e("aaron clickWithTrigger test")
}
//帶700毫秒過濾的點擊事件(方法2)
view.withTrigger(700).click {
L.e("aaron click test")
}
擴展:OnLazyClickListener用法
/**************** OnLazyClickListener用法 [Start]********************/
class TestActivity:Activity(), OnLazyClickListener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//Todo: your code
ivBack.setOnClickListener(this)
}
override fun onLazyClick(v: View) {
when(v.id){
R.id.ivBack-> onBackPressed()
}
}
}
/**************** OnLazyClickListener用法 [End]********************/
知識點:
1.利用了kotlin的擴展函數(shù)和擴展屬性。
2.擴展屬性不能額外添加filed橄务。所以我們利用了View的tag屬性來保存我們的triggerDelay和triggerLastTime
3.利用了kotlin的默認(rèn)參數(shù)幔托,減少函數(shù)重載。