Android 是否可以在不调用notify方法的情况下更新RecyclerView中的视图?
我的应用程序包含一个Android 是否可以在不调用notify方法的情况下更新RecyclerView中的视图?,android,android-recyclerview,android-progressbar,Android,Android Recyclerview,Android Progressbar,我的应用程序包含一个RecyclerView,每个项目中都有一个下载ProgressBar。我有一个DownloadManager类,它包含每个项目的下载进度。我希望我可以绘制我的RecyclerView,然后ProgressBar可以自我更新。我不希望每隔500毫秒调用notifyItemChanged() 将计时器上的ProgressBar设置为每X秒更新一次会阻止UI线程。我在想我的ViewHolder可能包含一个订阅DownloadManager类中的可观察对象的订阅者。但这似乎有点不对
RecyclerView
,每个项目中都有一个下载ProgressBar
。我有一个DownloadManager
类,它包含每个项目的下载进度。我希望我可以绘制我的RecyclerView
,然后ProgressBar
可以自我更新。我不希望每隔500毫秒调用notifyItemChanged()
将计时器上的ProgressBar
设置为每X秒更新一次会阻止UI线程。我在想我的ViewHolder
可能包含一个订阅DownloadManager
类中的可观察对象的订阅者。但这似乎有点不对劲
甚至可以在onBindViewHolder
中拥有独立的绘图功能吗?还是调用notifyItemChanged
更新视图的唯一解决方案
如果我将我的viewHolder
progressbar存储在哈希表中会怎么样?这样行吗?一切听起来都是个坏主意,救命啊 是的,有办法。其思想是将ProgressBar
实例传递给FileDownloader
,并使用onProgressUpdate
函数更新ProgressBar
。我以前也经历过类似的实现,因此我将分享一些代码示例,以简要介绍我必须做的事情
我必须编写一个FileDownloader
类,它启动了一个AsyncTask
处理文件下载操作。RecyclerView
的每个项目都有一个与之关联的ProgressBar
,因此我必须在列表中显示每个文件下载的进度
这是我的FileDownloader
类的快照
public class FileDownloader {
private String fileUrl;
private static File f;
private Context context;
private ProgressBar mProgressbar;
public FileDownloader(File file, String fileUrl, Context context, ProgressBar mProgressbar) {
this.f = file;
this.fileUrl = fileUrl;
this.context = context;
this.mProgressbar = mProgressbar;
this.mProgressbar.setProgress(0);
this.mProgressbar.setMax(10000);
new ImageDownloaderAsyncTask().execute(null, null, null);
}
public class ImageDownloaderAsyncTask extends
AsyncTask<Void, Integer, Integer> {
protected void doInBackground() throws IOException {
File dir = new File(DataHelper.DB_PATH);
if (!dir.exists()) dir.mkdir();
if (f != null && !f.exists()) f.createNewFile();
try {
URL url = new URL(fileUrl);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setDoInput(true);
connection.connect();
final String contentLengthStr = connection.getHeaderField("content-length");
InputStream input = connection.getInputStream();
String data1 = f.getPath();
FileOutputStream stream = new FileOutputStream(data1);
byte data[] = new byte[4096];
int count;
int progressCount = 0;
while ((count = input.read(data)) != -1) {
// allow canceling with back button
if (isCancelled()) input.close();
stream.write(data, 0, count);
progressCount = progressCount + count;
int progress = (int) (((progressCount * 1.0f) / Integer.parseInt(contentLengthStr)) * 10000);
publishProgress(progress);
}
stream.close();
} catch (Exception e) {
isDownloadCompleted = false;
e.printStackTrace();
}
}
@Override
protected Integer doInBackground(Void... params) {
try {
doInBackground();
} catch (IOException e) {
e.printStackTrace();
}
return 1;
}
protected void onProgressUpdate(Integer... values) {
mProgressbar.setProgress(values[0]);
}
protected void onPostExecute(Integer result) {
try {
mProgressbar.setVisibility(View.GONE);
// Tell the calling Activity that file has been downloaded. I had to implement this using a BroadcastReceiver.
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
我的ViewHolder
具有以下实现
private static class ViewHolder {
ProgressBar progressBar;
// ... Other elements in the list item
}
下载完成后,您需要通过在活动
或片段
中接收广播,在回收视图
上调用notifyDataSetChanged
希望有帮助 不要反对框架…使用notifyItemChanged(),这是确保通知所有相关人员(适配器、最终是视图和布局引擎)的正确方法。让数据交互者(您的下载管理器)通知您的演示者(具有对视图/布局和交互者的引用,并且可以处理数据流的内容)。我想你是在尝试破解一些在架构方面不应该太复杂的东西。
private static class ViewHolder {
ProgressBar progressBar;
// ... Other elements in the list item
}