在可观察对象发出一定数量的项目后触发一个动作

Trigger an action after certain amount of items emmited by an observable

我是 RxJava 的新手,在自定义我的流程时遇到了问题。这里的用例是:

我有一个 RecyclerView 和一个 GridLayoutManager 显示图像网格和一个页脚 TextView 将显示图像总数。换句话说,作为用户,我总共可以拥有 15 张图片,由 TextView 反映出来,它会说“15 张图片”,但网格仍然只会显示 4 张(将其理解为 "preview").现在,为了显示这些图像,在我创建的 Observable 的 onComplete() 中,我将调用 adapter.notifyDatasetChanged()。但是,如果列表包含 200 张图像,则等待这些图像出现是没有意义的。我想在列表中发出 4 个图像后立即通知适配器。我的 observable 是这样创建的:

Observable.just(user.getUserId())
            .subscribeOn(Schedulers.io())
            .map(this::getImageList)
            .flatMap(images -> Observable.fromIterable(images)
                .map(image -> image))
            .observeOn(AndroidSchedulers.mainThread());

这样做之后,我无法在 Observer.onNext() 中通知适配器,因为如果 images.size == 200 它将被通知 200 次(希望我在这里是正确的)。我不能在 Observer.onComplete() 中执行此操作,因为它会等待所有 200 个示例图像在适配器收到通知之前发出。我如何拦截该流程,在列表中的 4 个项目已发出时执行操作(通知适配器),但继续发出其余部分,这样我就可以显示带有总图像数量的正确页脚文本,而无需仅完成 4 个图片?

UPDATE - 出于超出此问题范围的目的,我需要 Observable 完成后的完整图像列表。我想显示其中的 4 个,用检索到的图像总数更新 TextView 并存储检索到的图像总数列表。

如果您修改 flatMap 中的代码,您仍然可以访问图像列表并获取其大小。

Observable.just(user.getUserId())
        .subscribeOn(Schedulers.io())
        .map(this::getImageList)
        .flatMap(images -> {
               // you can access images size here, update footer
               footer.setText(images.size() + " images");
               // pass full list of images to your view, i.e like this
               view.setImages(images);
               return Observable.fromIterable(images)
            })
            .take(4)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(image -> { 
                                // add image to grid 
                                },
                       error -> { 
                                // handle error
                                }
                       () ->    {
                                // four images were emitted, emission complete
                                adapter.notifyDatasetChanged();
                                });