在我的应用程序的简单部分中,我将此值定义为 ValueNotifier
:
final ValueNotifier<List<MediaDropDownStructure>> _mediaFoldersList = ValueNotifier<List<MediaDropDownStructure>>([]);
我在DropDownBottom
项目中使用了这个变量来填充它们并创建manu,然后我在StreamBuilder
中通过这段代码填充它:
StreamBuilder<List<MediaModel>>(
stream: _globalBloc.storageMediaBloc.imagesMedia$,
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const Center(
child: CircularProgressIndicator( ),
);
}
final List<MediaModel> _allImages = snapshot.data;
_mediaFoldersList.value = _allImages.map( (image) => MediaDropDownStructure( image.folder, image.folder ) ).toList();
final MediaModel _all = _allImages[0];
return GridView.builder(
...
我在 DropDownBotton
中使用它,就像:
child: ValueListenableBuilder(
valueListenable: _mediaFoldersList,
builder: (context, List<MediaDropDownStructure> items,child)=>DropdownButtonHideUnderline(
child: DropdownButton<MediaDropDownStructure>(
value: _chooseFolderName.value,
hint: Text("please choose",style: AppTheme.of(context).caption(),),
items: items.map((MediaDropDownStructure menuItem) {
return DropdownMenuItem<MediaDropDownStructure>(
value: menuItem,
child: Text(menuItem.folderPath),
);
}).toList(),
onChanged: (_) {},
),
),
),
我收到此错误:
The following assertion was thrown while dispatching notifications for ValueNotifier<List<MediaDropDownStructure>>:
setState() or markNeedsBuild() called during build.
This ValueListenableBuilder<List<MediaDropDownStructure>> widget cannot be marked as needing to build because the framework is already in the process of building widgets. A widget can be marked as needing to be built during the build phase only if one of its ancestors is currently building. This exception is allowed because the framework builds parent widgets before children, which means a dirty descendant will always be built. Otherwise, the framework might not visit this widget during this build phase.
The widget on which setState() or markNeedsBuild() was called was: ValueListenableBuilder<List<MediaDropDownStructure>>
dependencies: [_InheritedTheme, _LocalizationsScope-[GlobalKey#2b62a]]
state: _ValueListenableBuilderState<List<MediaDropDownStructure>>#6c134
The widget which was currently being built when the offending call was made was: StreamBuilder<List<MediaModel>>
dirty
state: _StreamBuilderBaseState<List<MediaModel>, AsyncSnapshot<List<MediaModel>>>#cbf2d
最佳答案
问题是,当streambuilder正在构建其状态时,同时_mediaFoldersList的值也会发生变化,因此它也将开始构建ValueListenableBuilder,并且会产生问题,因为两个构建器无法一起构建。
要解决这个问题,您可以在 1 微秒后更改 _mediaFoldersList 的值,以便 StreamBuilder 构建器完成其构建方法,然后 ValueListenableBuilder 可以构建。
像下面这样的crate方法。
changevaluenotifiervalue(_allImages) async {
await Future.delayed(Duration(microseconds: 1));
_mediaFoldersList.value = _allImages.map( (image) => MediaDropDownStructure( image.folder, image.folder ) ).toList();
}
在您要更改其值的位置调用此方法。
final List<MediaModel> _allImages = snapshot.data;
//_mediaFoldersList.value = _allImages.map( (image) => MediaDropDownStructure( image.folder, image.folder ) ).toList(); //commented
changevaluenotifiervalue(_allImages); // added
final MediaModel _all = _allImages[0];
关于flutter - 此 ValueListenableBuilder 小部件无法标记为需要构建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61554040/