Android   发布时间:2022-04-28  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了RxJava2去抖功能在RecyclerView – Android中无法正常工作大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试创建一个自定义 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(Co@R_944_10443@t co@R_944_10443@t) {
        super(co@R_944_10443@t);
        init();
    }

    public MBImageButton(Co@R_944_10443@t co@R_944_10443@t,AttributeSet attrs) {
        super(co@R_944_10443@t,attrs);
        init();
    }

    public MBImageButton(Co@R_944_10443@t co@R_944_10443@t,AttributeSet attrs,int defStyleAttr) {
        super(co@R_944_10443@t,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: 1
D/MBImageButton: Clicked: 2
D/MBImageButton: Clicked: 3
D/MBImageButton: Clicked: 4
D/MBImageButton: Clicked: 5
D/MBImageButton: Clicked: 6
D/MBImageButton: Clicked: 7
D/MBImageButton: Clicked: 8
D/MBImageButton: Clicked: 9
D/MBImageButton: Accumulated Clicks: 9

当我将此自定义ImageButton添加到Recycler@R_450_3868@Holder时,对于相同的点击次数,结果不正确:

D/MBImageButton: Clicked: 1
D/MBImageButton: Clicked: 2
D/MBImageButton: Clicked: 1
D/MBImageButton: Clicked: 3
D/MBImageButton: Clicked: 2
D/MBImageButton: Clicked: 4
D/MBImageButton: Accumulated Clicks: 4
D/MBImageButton: Clicked: 1
D/MBImageButton: Accumulated Clicks: 2
D/MBImageButton: Clicked: 2
D/MBImageButton: Accumulated Clicks: 2
D/MBImageButton: Accumulated Clicks: 0
D/MBImageButton: Clicked: 1
D/MBImageButton: Accumulated Clicks: 1
D/MBImageButton: Accumulated Clicks: 0
D/MBImageButton: Accumulated Clicks: 0

这是另外9次连续点击的结果:

D/MBImageButton: Clicked: 1
D/MBImageButton: Clicked: 2
D/MBImageButton: Clicked: 1
D/MBImageButton: Clicked: 3
D/MBImageButton: Clicked: 2
D/MBImageButton: Clicked: 4
D/MBImageButton: Clicked: 3
D/MBImageButton: Accumulated Clicks: 4
D/MBImageButton: Clicked: 1
D/MBImageButton: Accumulated Clicks: 3
D/MBImageButton: Accumulated Clicks: 1
D/MBImageButton: Accumulated Clicks: 0
D/MBImageButton: Clicked: 1
D/MBImageButton: Accumulated Clicks: 1
D/MBImageButton: Accumulated Clicks: 0
D/MBImageButton: Accumulated Clicks: 0
D/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 @R_450_3868@ = LayoutInflater.from(parent.getCo@R_944_10443@t()).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.getCo@R_944_10443@t(),iv_producImage,product.getImg(),R.drawable.ic_category_item);

            ib_decrease.setTag(position);
            ib_add.setTag(position);
        }
    }
}

解决方法

我得到了解决方

主要的问题是当我在RecyclerView适配器中滚动时,vies会从窗口中分离并调用onDetachedFromWindow函数,在该函数中我从observable取消订阅(disposE).

尝试的解决方案:

1.我添加了attachFunction

@Override
protected void onAttachedToWindow() {
    super.onAttachedToWindow();
    if (shouldDispoSEOnDetachFromWindow) {
        if (mDisposable != null) {
            if (mDisposable.isDisposed()) {
                initClickObservable();
                subscribe();
            }
        }
    }
}

2.删除了notifyItemChanged(位置)调用

通常我使用NotifyItemChange()进行一些修改后更新视图.现在我直接通过setText或类似函数更新视图.

它现在正常工作.

大佬总结

以上是大佬教程为你收集整理的RxJava2去抖功能在RecyclerView – Android中无法正常工作全部内容,希望文章能够帮你解决RxJava2去抖功能在RecyclerView – Android中无法正常工作所遇到的程序开发问题。

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

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。