我用debounce函数来完成这个.
自定义Imagebutton:
public class MBImagebutton extends Imagebutton { private AtomicInteger mCounter; private disposable mdisposable; private Observable<Object> observable; private OnAccumulatedRequestsRead mOnAccumulatedRequestsRead; private OnEverClickListener mOnEverClickListener; private int emitEveryMilli = 1000; // every 1 second by default private boolean shoulddispoSEOnDetachFromWindow = true; public MBImagebutton(Context context) { super(context); init(); } public MBImagebutton(Context context,AttributeSet attrs) { super(context,attrs); init(); } public MBImagebutton(Context context,AttributeSet attrs,int defStyleAttr) { super(context,attrs,defStyleAttr); init(); } public voID setAccumulatedClickListeners(OnEverClickListener onEverClickListener,OnAccumulatedRequestsRead onAccumulatedRequestsRead) { setonAccumulatedRequestsRead(onAccumulatedRequestsRead); setonEverClickListener(onEverClickListener); initClickObservable(); subscribe(); } private voID initClickObservable() { observable = Observable.create(emitter -> { emitter.setCancellable(() -> setonClickListener(null)); try { setonClickListener(vIEw -> { try { final int currentCount = mCounter.incrementAndGet(); Timber.d("Clicked: " + currentCount); if (mOnEverClickListener != null) { mOnEverClickListener.onEveryClickListener(currentCount); } emitter.onNext(new Object()); } catch (Exception e) { emitter.onError(e); } }); } catch (Exception e) { emitter.onError(e); } }).doOnSubscribe(disposable -> mdisposable = disposable) .debounce(emitEveryMilli,TimeUnit.MILliSECONDS); } private voID subscribe() { observable.subscribeOn(Schedulers.newThread()).observeOn(AndroIDSchedulers.mainThread()) .subscribe(o -> { try { final int count = mCounter.get(); if(count==0) return; mCounter.set(0); Timber.d("Accumulated Clicks: " + count); if (mOnAccumulatedRequestsRead != null) { mOnAccumulatedRequestsRead.onAccumulatedRequestsReady(count); } } catch (Exception e) { Timber.e(e); } },Timber::e); } private voID init() { mCounter = new AtomicInteger(0); } public voID disposeAccumulatedClickListeners() { if (mdisposable != null) { mdisposable.dispose(); } } public voID shoulddispoSEOnDetachFromWindow(boolean shoulddispoSEOnDetachFromWindow) { this.shoulddispoSEOnDetachFromWindow = shoulddispoSEOnDetachFromWindow; } public voID setEmitEveryMilliseconds(int emitEveryMilli) { this.emitEveryMilli = emitEveryMilli; initClickObservable(); subscribe(); } private voID setonEverClickListener(OnEverClickListener onEverClickListener) { mOnEverClickListener = onEverClickListener; } private voID setonAccumulatedRequestsRead(OnAccumulatedRequestsRead onAccumulatedRequestsRead) { mOnAccumulatedRequestsRead = onAccumulatedRequestsRead; } @OverrIDe protected voID onDetachedFromWindow() { super.onDetachedFromWindow(); if (shoulddispoSEOnDetachFromWindow) { if (mdisposable != null) { mdisposable.dispose(); } } } public interface OnAccumulatedRequestsRead { voID onAccumulatedRequestsReady(int count); } public interface OnEverClickListener { voID onEveryClickListener(int currentCount); }}
设置此imagebutton进行去抖动的功能是:
setAccumulatedClickListeners(OnEverClickListener,OnAccumulatedRequestsRead)
当我从RecyclerVIEw设置此视图时,一切正常,
当我按顺序点击9次时,结果如下所示:
D/MBImagebutton: Clicked: 1D/MBImagebutton: Clicked: 2D/MBImagebutton: Clicked: 3D/MBImagebutton: Clicked: 4D/MBImagebutton: Clicked: 5D/MBImagebutton: Clicked: 6D/MBImagebutton: Clicked: 7D/MBImagebutton: Clicked: 8D/MBImagebutton: Clicked: 9D/MBImagebutton: Accumulated Clicks: 9
当我将此自定义Imagebutton添加到RecyclerVIEw VIEwHolder时,对于相同的点击次数,结果不正确:
D/MBImagebutton: Clicked: 1D/MBImagebutton: Clicked: 2D/MBImagebutton: Clicked: 1D/MBImagebutton: Clicked: 3D/MBImagebutton: Clicked: 2D/MBImagebutton: Clicked: 4D/MBImagebutton: Accumulated Clicks: 4D/MBImagebutton: Clicked: 1D/MBImagebutton: Accumulated Clicks: 2D/MBImagebutton: Clicked: 2D/MBImagebutton: Accumulated Clicks: 2D/MBImagebutton: Accumulated Clicks: 0D/MBImagebutton: Clicked: 1D/MBImagebutton: Accumulated Clicks: 1D/MBImagebutton: Accumulated Clicks: 0D/MBImagebutton: Accumulated Clicks: 0
这是另外9次连续点击的结果:
D/MBImagebutton: Clicked: 1D/MBImagebutton: Clicked: 2D/MBImagebutton: Clicked: 1D/MBImagebutton: Clicked: 3D/MBImagebutton: Clicked: 2D/MBImagebutton: Clicked: 4D/MBImagebutton: Clicked: 3D/MBImagebutton: Accumulated Clicks: 4D/MBImagebutton: Clicked: 1D/MBImagebutton: Accumulated Clicks: 3D/MBImagebutton: Accumulated Clicks: 1D/MBImagebutton: Accumulated Clicks: 0D/MBImagebutton: Clicked: 1D/MBImagebutton: Accumulated Clicks: 1D/MBImagebutton: Accumulated Clicks: 0D/MBImagebutton: Accumulated Clicks: 0D/MBImagebutton: Accumulated Clicks: 0
在这两次我用相同的间隔时间点击,但当这个按钮添加到RecyclerVIEw时,它给出了奇怪的结果.
可能是什么问题?
更新:
我的Adapter简化了实现:
public class ProductRVAdapter extends BaseProductRVAdapter<ProductRVAdapter.ProductVH> { private ProductAdapterListener mProductAdapterListener; public ProductRVAdapter(List<Product> productList,ProductAdapterListener productAdapterListener) { super(productList); mProductAdapterListener = productAdapterListener; } @OverrIDe public ProductVH onCreateVIEwHolder(VIEwGroup parent,int vIEwType) { final VIEw vIEw = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_product,parent,false); return new ProductVH(vIEw); } @OverrIDe public voID onBindVIEwHolder(ProductVH holder,int position) { holder.bind(productList.get(position),position); holder.ib_decrease.setAccumulatedClickListeners(currentCount -> onProductAdapterDecreaseClicked.onClick(holder.ib_decrease),count -> { if (mProductAdapterListener != null) { mProductAdapterListener.onProductAdapterProductChangetoWSListener(productList.get(position),position,-count); } }); holder.ib_add.setAccumulatedClickListeners(currentCount -> onProductAdapteraddToCartClicked.onClick(holder.ib_add),count); } }); } public interface ProductAdapterListener { voID onProductAdapteraddToCartClicked(Product product,int position); voID onProductAdapterProductChangetoWSListener(Product product,int position,int amountChanged); voID onProductAdapterDecreaseClicked(Product product,int position); } public static class ProductVH extends RecyclerVIEw.VIEwHolder { @BindVIEw(R.ID.iv_productimage) ImageVIEw iv_producImage; @BindVIEw(R.ID.tv_productname) TextVIEw tv_productname; @BindVIEw(R.ID.tv_prodamount) MBTextVIEw tv_prodamount; @BindVIEw(R.ID.ib_decrease) MBImagebutton ib_decrease; @BindVIEw(R.ID.ib_add) MBImagebutton ib_add; ProductVH(VIEw itemVIEw) { super(itemVIEw); ButterKnife.bind(this,itemVIEw); } public voID bind(Product product,int position) { tv_productname.setText(product.getname()); tv_prodamount.setText(product.getAmount()); ImageLoader.loadImage(iv_producImage.getContext(),iv_producImage,product.getimg(),R.drawable.ic_category_item); ib_decrease.setTag(position); ib_add.setTag(position); } }}解决方法 我得到了解决方案
主要的问题是当我在RecyclerVIEw适配器中滚动时,vIEs会从窗口中分离并调用onDetachedFromWindow函数,在该函数中我从observable取消订阅(dispose).
尝试的解决方案:
1.我添加了attachFunction
@OverrIDeprotected voID onAttachedToWindow() { super.onAttachedToWindow(); if (shoulddispoSEOnDetachFromWindow) { if (mdisposable != null) { if (mdisposable.isdisposed()) { initClickObservable(); subscribe(); } } }}
2.删除了notifyItemChanged(位置)调用
通常我使用notifyItemChange()进行一些修改后更新视图.现在我直接通过setText或类似函数更新视图.
它现在正常工作.
总结以上是内存溢出为你收集整理的RxJava2去抖功能在RecyclerView – Android中无法正常工作全部内容,希望文章能够帮你解决RxJava2去抖功能在RecyclerView – Android中无法正常工作所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)