這篇文章主要介紹了Android中View事件防抖的處理方案,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
侵入式防抖處理(NoShakeClickListener) implements View.OnClickListener
無侵入式防抖處理(NoShakeClickListener2) not implements View.OnClickListener
1. 既適用于單個View事件防抖, 也適用于Adapter中ItemView事件防抖
2. 如果事件為跳轉到新的Activity, 該Activity啟動模型應為android:launchMode="singleTop"
public abstract class NoShakeClickListener implements View.OnClickListener {
private long mTimeInterval = 500L;
/**
* 最近一次點擊的時間
*/
private long mLastClickTime;
/**
* 最近一次點擊的控件ID
*/
private int mLastClickViewId;
public NoShakeClickListener() {
}
public NoShakeClickListener(long interval) {
this.mTimeInterval = interval;
}
@Override
public void onClick(View v) {
final boolean isFastClick = isFastDoubleClick(v, this.mTimeInterval);
if (isFastClick) {
onFastClick(v);
} else {
onSingleClick(v);
}
}
/**
* 是否是快速點擊
*
* @param v 點擊的控件
* @param interval 時間間期(毫秒)
* @return true:是,false:不是
*/
private boolean isFastDoubleClick(View v, long interval) {
int viewId = v.getId();
long nowTime = System.currentTimeMillis();
long timeInterval = Math.abs(nowTime - mLastClickTime);
if (timeInterval < interval && viewId == mLastClickViewId) {
// 快速點擊事件
return true;
} else {
// 單次點擊事件
mLastClickTime = nowTime;
mLastClickViewId = viewId;
return false;
}
}
protected void onFastClick(View v) {}
protected abstract void onSingleClick(View v);
}可簡寫為
public abstract class NoShakeListener implements OnClickListener {
private long mLastClickTime = 0;
private boolean isFastDoubleClick() {
long nowTime = System.currentTimeMillis();
if (Math.abs(nowTime - mLastClickTime) < 500) {
return true; // 快速點擊事件
} else {
mLastClickTime = nowTime;
return false; // 單次點擊事件
}
}
@Override
public void onClick(View v) {
if (isFastDoubleClick()) {
onFastClick(v);
} else {
onSingleClick(v);
}
}
protected void onFastClick(View v) {
}
protected abstract void onSingleClick(View v);
}abstract class NoShakeClickListener @JvmOverloads constructor(interval: Long = 500L) : View.OnClickListener {
private var mTimeInterval = 500L
private var mLastClickTime: Long = 0 //最近一次點擊的時間
private var mLastClickViewId = 0 //最近一次點擊的控件ID
init {
mTimeInterval = interval
}
override fun onClick(v: View) {
if (isFastDoubleClick(v, mTimeInterval)) onFastClick(v) else onSingleClick(v)
}
/**
* 是否是快速點擊
*
* @param v 點擊的控件
* @param interval 時間間期(毫秒)
* @return true:是,false:不是
*/
private fun isFastDoubleClick(v: View, interval: Long): Boolean {
val viewId = v.id
val nowTime = System.currentTimeMillis()
val timeInterval = abs(nowTime - mLastClickTime)
return if (timeInterval < interval && viewId == mLastClickViewId) {
// 快速點擊事件
true
} else {
// 單次點擊事件
mLastClickTime = nowTime
mLastClickViewId = viewId
false
}
}
protected open fun onFastClick(v: View?) {}
protected abstract fun onSingleClick(v: View?)
}差點忘了... 相應的擴展函數:
fun View?.noShake(block: (v: View?) -> Unit) {
this?.apply {
setOnClickListener(object : NoShakeClickListener() {
override fun onSingleClick(v: View?) {
block.invoke(v)
}
})
}
}inline fun <T : View> T.noShake(crossinline listener: T.() -> Unit) = this.noShake(1000, listener)
inline fun <T : View> T.noShake(windowDuration: Long = 500, crossinline listener : T.() -> Unit) =
RxView.clicks(this)
.throttleFirst(windowDuration, TimeUnit.MILLISECONDS)
.subscribe(object : Observer<Any> {
override fun onSubscribe(d: Disposable) {}
override fun onError(e: Throwable) {}
override fun onComplete() {}
override fun onNext(o: Any) {
listener()
}
})1 移除了對View.OnClickListener的依賴, 在不破壞原有代碼已設置好的OnClickListener基礎上繼續處理事件防抖;
2 支持簡單處理事件和泛型回調
/**
* 事件防抖
* 注: 不僅適用于 View , 其他控件如: MenuItem 同樣適用
*
* 1.既適用于單個`View`事件防抖, 也適用于`Adapter`中`ItemView`事件防抖
* 2.如果事件為跳轉到新的`Activity`, 該`Activity`啟動模型應為`android:launchMode="singleTop"`
*/
open class NoShakeClickListener2 @JvmOverloads constructor(interval: Long = 500L) {
private var mTimeInterval = 500L
private var mLastClickTime: Long = 0 //最近一次點擊的時間
private var mLastClick: Any? = null //最近一次點擊的控件 View or MenuItem ...
init {
mTimeInterval = interval
}
fun proceedClick() {
if (isFastClick(null, mTimeInterval)) onFastClick(null) else onSingleClick(null)
}
fun <T> proceedClick(item: T?) {
if (isFastClick(item, mTimeInterval)) onFastClick(item) else onSingleClick(item)
}
/**
* 是否是快速點擊
*
* @param item 點擊的控件 View or MenuItem ...
* @param interval 時間間期(毫秒)
* @return true:是,false:不是
*/
private fun <T> isFastClick(item: T?, interval: Long): Boolean {
val nowTime = System.currentTimeMillis()
val timeInterval = abs(nowTime - mLastClickTime)
return if (timeInterval < interval && item == mLastClick) {
// 快速點擊事件
true
} else {
// 單次點擊事件
mLastClickTime = nowTime
mLastClick = item
false
}
}
protected open fun onFastClick(item: Any?) {}
protected open fun onSingleClick(item: Any?) {}
}1 簡單使用
//快速點擊事件
val fastClick=object :NoShakeClickListener2(){
override fun onFastClick(item: Any?) {
super.onFastClick(item)
//此時 item == null
Log.e("123", "onFastClick Click")
}
}
BottomNavigationView.setOnNavigationItemSelectedListener {
switchPage(it.itemId)
fastClick.proceedClick()
true
}2 回傳參數
//快速點擊事件
val fastClick=object :NoShakeClickListener2(){
override fun onFastClick(item: Any?) {
super.onFastClick(item)
//此時 item == null 為 proceedClick(it) 中的 it
Log.e("123", "onFastClick Click")
}
}
BottomNavigationView.setOnNavigationItemSelectedListener {
switchPage(it.itemId)
fastClick.proceedClick(it)
true
}感謝你能夠認真閱讀完這篇文章,希望小編分享的“Android中View事件防抖的處理方案”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。