防抖有多种方案
- 点击后设置enable(boolean)缺点:防抖后连点击效果都没了
- 自定义OnClickListener,内部记录时间等
- 使用Rxbinding
- 使用Rxjava的throttleFirst
- 等
相信有不少小伙伴和我一样不想因为这个小功能引入Rxbinding,所以会选择使用RxJava的throttleFirst
在java中
/**
* @author GreenhairTurtle
**/
public class ViewClickOnSubscribe implements ObservableOnSubscribe<View> {
private final View view;
public ViewClickOnSubscribe(View view) {
this.view = Objects.requireNonNull(view);
}
@Override
public void subscribe(ObservableEmitter<View> emitter) {
view.setOnClickListener(v -> {
if (!emitter.isDisposed()) {
emitter.onNext(v);
}
});
}
}
使用方式
Observable.create(new ViewClickOnSubscribe(v))
.throttleFirst(milliseconds, TimeUnit.MILLISECONDS)
.subscribe(//do)
个人认为这样使用,并不算很优雅,感觉太难看了,和自定义OnClickListener实际上没有多大区别
不过Kotlin的扩展函数为这种实现方式带来了很好的体验
@JvmOverloads
fun View.setOnShakeProofClickListener( windowDuration: Long = 1000,
unit: TimeUnit = TimeUnit.MILLISECONDS,
listener: (view: View) -> Unit): Disposable {
return Observable.create(ObservableOnSubscribe<View> { emitter ->
setOnClickListener {
if (!emitter.isDisposed) {
emitter.onNext(it)
}
}
}).throttleFirst(windowDuration, unit)
.subscribe { listener(it) }
}
使用
view.setOnShakeProofClickListener { //do }
一切都和正常的设置点击事件一样
这个扩展函数返回了Disposable,你可以将其添加到自己的CompositeDisposable中然后在onDestory中取消订阅
显然,你可以定义一个扩展函数
fun Disposable.addTo(compositeDisposable: CompositeDisposable) {
compositeDisposable.add(this)
}
这样,调用就变成了
view.setOnShakeProofClickListener { //do }
.addTo(compositeDisposable)
override fun onDestroy() {
compositeDisposable.clear()
}
你可以使用和LifeCycle绑定的AutoDisposable来实现自定义取消订阅
/**
* https://medium.com/mindorks/autodisposable-for-rxjava-with-lifecycle-architecture-component23dfcfa83a2
**/
class AutoDisposable : LifecycleObserver {
lateinit var compositeDisposable: CompositeDisposable
fun bind(lifecycle: Lifecycle) {
lifecycle.addObserver(this)
compositeDisposable = CompositeDisposable()
}
fun add(disposable: Disposable) {
if (::compositeDisposable.isInitialized) {
compositeDisposable.add(disposable)
} else {
throw NotImplementedError("must bind AutoDisposable to a Lifecycle first")
}
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun onDestroy() {
compositeDisposable.clear()
}
}
fun Disposable.addTo(autoDisposable: AutoDisposable) {
autoDisposable.add(this)
}
val autoDisposable by lazy {
AutoDisposable().apply { bind(lifecycle) }
}
这样,调用就变成了
view.setOnShakeProofClickListener { //do }
.addTo(autoDisposable)
结束~
网友评论