ProgressBar элемента в RecyclerView PopupWindow как раскрывающийся список элемента RecyclerView - PullRequest
0 голосов
/ 06 мая 2019

Звучит глупо, верно? У меня есть RecyclerView с карточками предметов. Эти карты имеют кнопку, которая отображает всплывающее окно со списком «вложений» в другом RecyclerView. Эти карты вложений имеют кнопку, с помощью которой вы можете загрузить их, и процесс загрузки должен отображаться на индикаторе выполнения.

Теперь я не могу найти правильный способ обновления индикатора выполнения при выполнении параллельных асинхронных загрузок.

По сути, у меня есть asyncTask с прослушивателем прогресса, который обновляет поле прогресса в объекте AttachmentData (данные, связанные с картами вложений). Предполагается, что владелец может прочитать ход выполнения AttachmentData и обновить индикатор выполнения ...

... во всплывающем окне элемента в представлении переработчика.

Моя проблема в том, что всякий раз, когда я запускаю новый asyncTask поверх других AsyncTask, последний asyncTask перехватывает весь прогресс предыдущих, и вместо трех вложений, показывающих их индивидуальный прогресс, у меня есть два вложения, показывающие их замороженный прогресс (вплоть до щелчка по третьему вложению), а третье вложение показывает прогресс трех вложений, обновляя каждый раз, когда одно из них обновляет свой собственный прогресс.

Это довольно запутанно.

Дело в том, что у меня есть основания подозревать, что это не имеет никакого отношения к RecyclerView, поскольку отправляемые мной уведомления ведут себя именно так.

Все происходит при привязке данных в ViewHolder

  public <T extends DownloadableData> void bindData(T data, ItemProgressListener ipl) {
    this.data = data;
    this.ipl = ipl;

//....
    button.setOnClickListener(v->openDoc());

//....
}


public void openDoc(){
                data.pdfStatus = PDF_DOWNLOADING;


                NotificationCompat.Builder builder = new NotificationCompat.Builder(parentFragment.getActivity(), CHANNEL_ID)
                        .setSmallIcon(R.drawable.logo_white)
                        .setContentTitle("Downloading " + data.title)
                        .setContentText("Current Progress: " + data.progress + " %")
                        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                        .setStyle(new NotificationCompat.BigTextStyle()
                                .bigText("Current Progress: " + data.progress + " %"))
                        .setAutoCancel(false);

                int PROGRESS_MAX = 100;
                builder.setProgress(PROGRESS_MAX, 0, false);


                int notificationId = Integer.parseInt(data.uuid);
                // notificationId is a unique int for each notification that you must define
                notificationManager.notify(notificationId, builder.build());

                CloudManager.PaperDownloader pd = new CloudManager.PaperDownloader() {
                    @Override
                    public String getFilePath() {
                        return data.filepath;
                    }

                    @Override
                    public void progressUpdate(Integer... values) {

                        data.pdfStatus = PDF_DOWNLOADING;
                        data.setProgress(values[0]);

                        if ((values[0] % 5 == 1 || values[0] == 100) && data.previousProgress < data.progress) {
                            if (ipl != null)
                                ipl.onItemProgressChanged(position, data);

                            builder.setContentText("Current Progress: " + values[0] + " %")
                                    .setStyle(new NotificationCompat.BigTextStyle()
                                            .bigText("Current Progress: " + values[0] + " %"))
                                    .setProgress(PROGRESS_MAX, values[0], false);
                            notificationManager.notify(notificationId, builder.build());
                        }

                    }

                    @Override
                    public void downloadSuccess(Integer... positions) {
                        data.pdfStatus = PDF_DOWNLOADED;
                        data.setProgress(100);
                        if (ipl != null)
                            ipl.onItemProgressChanged(position, data);

                        builder.setStyle(new NotificationCompat.BigTextStyle()
                                .bigText("Current Progress: 100 %"))
                                .setProgress(0, 0, false);

                        notificationManager.notify(notificationId, builder.build());
                        notificationManager.cancel(notificationId);


                    }

                    @Override
                    public void downloadCancelled(String errorMessage) {
                        data.pdfStatus = PDF_DOWNLOAD_CANCELLED;
                        data.setProgress(-1);
                        if (ipl != null)
                            ipl.onItemProgressChanged(position, data);

                        builder.setStyle(new NotificationCompat.BigTextStyle()
                                .bigText("Operation has been cancelled!:\n" + errorMessage))
                                .setProgress(0, 0, false);

                        notificationManager.notify(notificationId, builder.build());


                    }

                    @Override
                    public void downloadFailed(String errorMessage) {
                        data.pdfStatus = PDF_DOWNLOAD_FAILED;
                        data.setProgress(-1);
                        if (ipl != null)
                            ipl.onItemProgressChanged(position, data);

                        builder.setStyle(new NotificationCompat.BigTextStyle()
                                .bigText("Operation has been cancelled!:\n" + errorMessage))
                                .setProgress(0, 0, false);

                        notificationManager.notify(notificationId, builder.build());


                    }
                };


                try {
                    String finalPath = cloudManager.getRemoteFilePath(data.filepath, true);

                    cloudManager.getArticlePdfDownloader(pd)
                          .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, finalPath);


                } catch (NullPointerException npe) {
                    npe.printStackTrace();
                    parentFragment.alert(context.getString(R.string.alert_cloud_not_set));
                }

}

Для ясности, "ipl" - это еще один интерфейс, переданный адаптером держателю, в попытке от меня обновить как можно меньше карт в процессе загрузки. Самый ленивый / самый глупый способ определения ipl:

 adapter.setOnItemProgressListener((position, data)->adapter.notifyDataSetChanged());

Наконец, bindData вызывается адаптером

@Override
public void onBindViewHolder(@NonNull AbstractDownloadableHolder holder, int position) {
    DownloadableData currentPaper = this.dataList.get(position);

    holder.bindData(currentPaper, ipl);
}
...