flutter 从外部源更新ListView.builder中单个项的状态

uurity8g  于 2023-10-22  发布在  Flutter
关注(0)|答案(1)|浏览(185)

我使用ListView.builder来管理一长串小部件,每个小部件都有一个进度条。
我已经查看了其他答案,并确保由ListView.builder构造的每个Widget都有自己的状态。在我的例子中,ConversionGroupWidget管理自己的状态。
问题是更新来自Stream。当监听流更新时,如果需要,我会创建一个新的小部件,然后setState()刷新整个列表。但是,如果更新只是一个进度更改,我如何从ListView中选择需要setState()调用的单个项目?下面是带有TODO注解的行。

class ProgressView extends StatefulWidget {
  final Stream<ProgressStatus> statusStream;

  const ProgressView({super.key, required this.statusStream});

  @override
  State<ProgressView> createState() => _ProgressViewState();
}

class _ProgressViewState extends State<ProgressView> {
  final ProgressData conversionProgress = ProgressData();

  @override
  Widget build(BuildContext context) {
    widget.statusStream.listen((update) async {
      final group = conversionProgress.groupToUpdate(update);

      if (group == null) {
        await conversionProgress.addConversionGroup(update);
        setState(() {});
      } else {
        // TODO!
      }
    });
    return ListView.builder(
        itemCount: conversionProgress.conversionGroups.length,
        itemBuilder: (context, idx) {
          var group = conversionProgress.conversionGroups[idx];

          return Container(
              padding: Style.prefsPaneSideInsets,
              child: Column(children: [
                Style.prefsPaneSectionVSpacer,
                ConversionGroupWidget(
                  groupStatus: group,
                )
              ]));
        });
  }
}
ycggw6v2

ycggw6v21#

问题是,让单个Widget成为无状态的,从根本上说与Stream不兼容。
Stream事件更新Widget s,因此根据定义,如果Widget是无状态的,则无法更新。这导致了一个大的全局状态,并调用setState()来立即更新所有内容。
我通过使用有状态的小部件并让每个Widget在其构造函数中接受一个经过过滤的Stream来解决这个问题。然后在initState中,状态在widget.stream上调用listen()并以这种方式更新自己。

相关问题