[英]Is it possible to update a View in RecyclerView without calling a notify method?
我的應用程序包含一個RecyclerView
,每個項目中都有一個下載的ProgressBar
。 我有一個DownloadManager
類,其中包含每個項目的下載進度。 我希望可以繪制我的RecyclerView
,然后ProgressBar
可以自我更新。 我寧願不要每500毫秒調用notifyItemChanged()
。
將Timer
上的ProgressBar
設置為每隔X秒更新一次,將阻止UI線程。 我在想我的ViewHolder
可能包含一個訂閱者,該訂閱者訂閱了DownloadManager
類中的Observable。 但是那件事似乎是錯誤的。
甚至可能在onBindViewHolder
內部具有獨立的繪制功能? 或者是調用notifyItemChanged
更新視圖的唯一解決方案?
如果我將viewHolder
progressBars存儲在哈希表中怎么辦? 那行得通嗎? 一切聽起來像個壞主意,求助!
是的,有辦法。 這個想法是將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();
}
}
}
}
現在,在RecyclerView
,我必須像這樣在onBindViewHolder
初始化FileDownloader
的新實例。
// In order to start a download on a button click.
new FileDownloader(File file, fileUrl, getActivity(), holder.progressBar);
我的ViewHolder
具有以下實現。
private static class ViewHolder {
ProgressBar progressBar;
// ... Other elements in the list item
}
下載完成后,您需要在Activity
或Fragment
收到廣播,從而需要在RecyclerView
上調用notifyDataSetChanged
。
希望有幫助!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.