0

添付ファイルのリストをアップロードし、各要素が繰り返されるたびに各要素のステータスを更新しようとしています。アップロードが正常に完了した場合は、uploadSucceded = true、それ以外の場合は false を出力します。

Future<void> uploadAttachments() async {
    int uploadableAttachmentIndex = 0;
    emit(state.copyWith(isUploadingAttachments: true));
    final attachments = generateFormAttachmentList();

    await Future.forEach(
      attachments,
      (UploadableAttachment attachment) async {
        final success = await uploadFile(attachment);
        if (success) {
          debugPrint('SUCCESS!!!!!');
          emit(state.copyWith(
            uploadableAttachments: state.uploadableAttachments!
              ..[uploadableAttachmentIndex].uploadSucceded = true,
          ));
        } else {
          debugPrint('FAILED!!!');
          emit(state.copyWith(
              uploadableAttachments: state.uploadableAttachments!
                ..[uploadableAttachmentIndex].uploadSucceded = false,
              isUpdatingTask: false,
              taskUpdateError: 'Error uploading attachment',
              attachmentUploadsFailed: true));
        }
        uploadableAttachmentIndex++;
      }
    );
    emit(state.copyWith(isUploadingAttachments: false));
  }

値が設定されている間、関数の最後に発行するまで再構築はトリガーされず、アップロードのステータスが一度に再構築されます。forEach 内の再構築がトリガーされない理由はわかりませんが、問題はこの関数にあると思います。ブロック ビルダーは次のようになります。

class _UploadAttachmentsPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocBuilder<TaskDetailsCubit, TaskDetailsState>(builder: (context, state) {
      return Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          state.attachmentUploadsFailed
              ? _UploadErrorWidget()
              : _UploadPageHeader(state.isUploadingAttachments),
          SizedBox(height: 40),
          Expanded(
            child: ListView.builder(
              scrollDirection: Axis.vertical,
              shrinkWrap: true,
              itemCount: state.uploadableAttachments!.length,
              itemBuilder: (context, index) {
                return _UploadProgressListItem(file: state.uploadableAttachments![index]);
              },
            ),
          ),
        ],
      );
    });
  }
}

uploadSucceded が設定されると、UploadProgressListItem が再構築されます。

class _UploadProgressListItem extends StatelessWidget {
  final UploadableAttachment file;

  _UploadProgressListItem({required this.file});

  Widget getListTileIcon() {
    if (file.uploadSucceded == true)
      return Icon(Icons.check, color: CoreTheme.green);
    else if (file.uploadSucceded == false)
      return Icon(Icons.error, color: CoreTheme.error);
    else
      return CircularProgressIndicator();
  }

  Widget getSubtitle() {
    if (file.uploadSucceded == true)
      return Text(
        'Complete',
        style: CoreTheme.textStyleLabel(color: FontColor.green),
      );
    else if (file.uploadSucceded == false)
      return Text(
        'Problem Uploading',
        style: CoreTheme.textStyleLabel(color: FontColor.red),
      );
    else
      return Text('Uploading', style: CoreTheme.textStyleLabel());
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(14.0),
      child: ListTile(
        leading: getListTileIcon(),
        title: Text(
          file.filename,
          overflow: TextOverflow.ellipsis,
          style: CoreTheme.textStyleBodyRegular(),
        ),
        subtitle: getSubtitle(),
      ),
    );
  }
}

class UploadableAttachment {
  bool? uploadSucceded;
  final File file;
  final String filename;
  final String fieldKey;

  UploadableAttachment({
    this.uploadSucceded,
    required this.file,
    required this.filename,
    required this.fieldKey,
  });
}

私は間違った非同期ルートを取っているのではないかと思っています。リストの代わりにストリームを使用する必要がありますか? BlocBuilder の代わりに BlocListener または BlocConsumer を使用する必要がありますか?

4

1 に答える 1