RxJava2去抖功能在RecyclerView – Android中无法正常工作

RxJava2去抖功能在RecyclerView – Android中无法正常工作,第1张

概述我正在尝试创建一个自定义 ImageButton,当用户停止单击按钮1秒钟时,它将累积点击并触发事件. 我用debounce函数来完成这个. 自定义ImageButton: public class MBImageButton extends ImageButton { private AtomicInteger mCounter; private Disposable mDis 我正在尝试创建一个自定义 Imagebutton,当用户停止单击按钮1秒钟时,它将累积点击并触发事件.

我用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中无法正常工作所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1148255.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存