java - 在 ViewHolder 中使用 RxJava
问题描述
我在一个图像编辑安卓应用程序上工作。在这个应用程序中,用户可以下载资产。因为这些资源很大,所以我使用 DownloadManager 来下载它们。用户可以下载的项目显示在 RecyclerView 中。我要做的是将DownloadManager下载任务绑定到RecyclerView中的item,让用户看到下载的进度。这是我为获取下载进度而编写的 Rx 包装器。
private Observable<Integer> createDownloadProgressListener(long downloadId) {
return Observable.create(observer -> {
boolean downloading = true;
while (downloading) {
DownloadManager.Query q = new DownloadManager.Query();
q.setFilterById(downloadId);
Cursor cursor = downloadManager.query(q);
cursor.moveToFirst();
int bytes_downloaded = cursor.getInt(cursor
.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
int bytes_total = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
if (cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)) == DownloadManager.STATUS_SUCCESSFUL) {
downloading = false;
observer.onNext(100);
observer.onCompleted();
}
final int dlProgress = (int) ((bytes_downloaded * 100L) / bytes_total);
observer.onNext(dlProgress);
Log.d(TAG, "Download progress: " + dlProgress);
cursor.close();
}
});
}
这是我在 ViewHolder 的绑定方法中绑定到这个 observable 的方法:
private void bindEffectDownloadTask() {
if (item.getDownloadRefId() != null && baseActivity.rxDownloadManager.getDownloadProgressListener(item.getDownloadRefId()) != null) { baseActivity.rxDownloadManager.getDownloadProgressListener(item.getDownloadRefId())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnSubscribe(() -> item.setDownloading(true))
.doOnTerminate(() -> item.setDownloading(false))
.subscribe(progress ->
updateDownloadProgress(progress),
error -> {
Log.d(TAG, "Error in download task: " + error.getMessage());
},
() -> {
downloadedState();
});
}
}
我的问题是updateDownloadProgress
(我设置自定义圆形进度视图的进度)不仅会更新当前的 ViewHolder,还会更新其他 ViewHolder。如何确保仅更新当前的 ViewHolder?或者如果这种方法完全错误,那么在 RecyclerView 项目中处理异步数据流的最佳实践是什么?也许我应该从 BehaviorSubject 发出下载进度和对象 ID,在我的活动中订阅它并在适配器中找到要更新的项目并用进度更新它们?
编辑
updateDownloadProgress
方法:
void updateDownloadProgress(int progress) {
downloadButton.setVisibility(View.GONE);
downloadProgressBar.setVisibility(View.VISIBLE);
downloadProgressBar.setProgress(progress);
}
解决方案
您可以使用 setTag ang getTag 以便仅更新当前 ViewHolder
推荐阅读
- sql - 拆分字母数字字符串时遇到问题
- c++ - C++句柄类抽象
- java - com/onesignal/androidsdk/GradleProjectPlugin 已由 Java 运行时的更新版本编译
- javascript - 使用 menuPortalTarget 时如何修复 react-select 下拉菜单的样式
- r - 合并季度和月度财务数据
- python - Python IMAP 检查 UID 大于存储的 UID 的消息消息
- c - 试图理解反编译器抛出的伪代码
- java - 使用 JPA 存储库获取标识符列和另一列
- r - 重新编码只是整个值一部分的字符值
- javascript - 如何选择 Facebook 发布工具页面上的所有复选框?