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
}